Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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    logstore_database
  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\contextlist;
  32  use core_privacy\local\request\approved_contextlist;
  33  use core_privacy\local\request\transform;
  34  use core_privacy\local\request\writer;
  35  use logstore_database\privacy\provider;
  36  
  37  require_once (__DIR__ . '/fixtures/event.php');
  38  
  39  /**
  40   * Data provider testcase class.
  41   *
  42   * This testcase is almost identical to the logstore_standard testcase, aside from the
  43   * initialisation of the relevant logstore obviously.
  44   *
  45   * @package    logstore_database
  46   * @category   test
  47   * @copyright  2018 Frédéric Massart
  48   * @author     Frédéric Massart <fred@branchup.tech>
  49   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  50   */
  51  class logstore_database_privacy_testcase extends provider_testcase {
  52  
  53      public function setUp() {
  54          global $CFG;
  55          $this->resetAfterTest();
  56          $this->preventResetByRollback(); // Logging waits till the transaction gets committed.
  57  
  58          // Fake the settings, we will abuse the standard plugin table here...
  59          set_config('dbdriver', $CFG->dblibrary . '/' . $CFG->dbtype, 'logstore_database');
  60          set_config('dbhost', $CFG->dbhost, 'logstore_database');
  61          set_config('dbuser', $CFG->dbuser, 'logstore_database');
  62          set_config('dbpass', $CFG->dbpass, 'logstore_database');
  63          set_config('dbname', $CFG->dbname, 'logstore_database');
  64          set_config('dbtable', $CFG->prefix . 'logstore_standard_log', 'logstore_database');
  65          if (!empty($CFG->dboptions['dbpersist'])) {
  66              set_config('dbpersist', 1, 'logstore_database');
  67          } else {
  68              set_config('dbpersist', 0, 'logstore_database');
  69          }
  70          if (!empty($CFG->dboptions['dbsocket'])) {
  71              set_config('dbsocket', $CFG->dboptions['dbsocket'], 'logstore_database');
  72          } else {
  73              set_config('dbsocket', '', 'logstore_database');
  74          }
  75          if (!empty($CFG->dboptions['dbport'])) {
  76              set_config('dbport', $CFG->dboptions['dbport'], 'logstore_database');
  77          } else {
  78              set_config('dbport', '', 'logstore_database');
  79          }
  80          if (!empty($CFG->dboptions['dbschema'])) {
  81              set_config('dbschema', $CFG->dboptions['dbschema'], 'logstore_database');
  82          } else {
  83              set_config('dbschema', '', 'logstore_database');
  84          }
  85          if (!empty($CFG->dboptions['dbcollation'])) {
  86              set_config('dbcollation', $CFG->dboptions['dbcollation'], 'logstore_database');
  87          } else {
  88              set_config('dbcollation', '', 'logstore_database');
  89          }
  90          if (!empty($CFG->dboptions['dbhandlesoptions'])) {
  91              set_config('dbhandlesoptions', $CFG->dboptions['dbhandlesoptions'], 'logstore_database');
  92          } else {
  93              set_config('dbhandlesoptions', false, 'logstore_database');
  94          }
  95      }
  96  
  97      public function test_get_contexts_for_userid() {
  98          $admin = \core_user::get_user(2);
  99          $u1 = $this->getDataGenerator()->create_user();
 100          $u2 = $this->getDataGenerator()->create_user();
 101          $u3 = $this->getDataGenerator()->create_user();
 102  
 103          $c1 = $this->getDataGenerator()->create_course();
 104          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
 105          $c2 = $this->getDataGenerator()->create_course();
 106          $cm2 = $this->getDataGenerator()->create_module('url', ['course' => $c2]);
 107  
 108          $sysctx = context_system::instance();
 109          $c1ctx = context_course::instance($c1->id);
 110          $c2ctx = context_course::instance($c2->id);
 111          $cm1ctx = context_module::instance($cm1->cmid);
 112          $cm2ctx = context_module::instance($cm2->cmid);
 113  
 114          $this->enable_logging();
 115          $manager = get_log_manager(true);
 116  
 117          // User 1 is the author.
 118          $this->setUser($u1);
 119          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), []);
 120          $e = \logstore_database\event\unittest_executed::create(['context' => $cm1ctx]);
 121          $e->trigger();
 122          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$cm1ctx]);
 123  
 124          // User 2 is the related user.
 125          $this->setUser(0);
 126          $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), []);
 127          $e = \logstore_database\event\unittest_executed::create(['context' => $cm2ctx, 'relateduserid' => $u2->id]);
 128          $e->trigger();
 129          $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), [$cm2ctx]);
 130  
 131          // Admin user is the real user.
 132          $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), []);
 133          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), []);
 134          $this->setAdminUser();
 135          \core\session\manager::loginas($u3->id, $sysctx);
 136          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 137          $e->trigger();
 138          $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx]);
 139          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx]);
 140  
 141          // By admin user masquerading u1 related to u3.
 142          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$cm1ctx]);
 143          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx]);
 144          $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx]);
 145          $this->setAdminUser();
 146          \core\session\manager::loginas($u1->id, context_system::instance());
 147          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u3->id]);
 148          $e->trigger();
 149          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$sysctx, $cm1ctx, $c2ctx]);
 150          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx, $c1ctx, $c2ctx]);
 151          $this->assert_contextlist_equals($this->get_contextlist_for_user($admin), [$sysctx, $c1ctx, $c2ctx]);
 152      }
 153  
 154      /**
 155       * Check that user IDs are returned for a given context.
 156       */
 157      public function test_add_userids_for_context() {
 158          $admin = \core_user::get_user(2);
 159          $u1 = $this->getDataGenerator()->create_user();
 160          $u2 = $this->getDataGenerator()->create_user();
 161          $u3 = $this->getDataGenerator()->create_user();
 162          $u4 = $this->getDataGenerator()->create_user();
 163  
 164          $c1 = $this->getDataGenerator()->create_course();
 165  
 166          $sysctx = context_system::instance();
 167          $c1ctx = context_course::instance($c1->id);
 168  
 169          $this->enable_logging();
 170          $manager = get_log_manager(true);
 171  
 172          $userlist = new \core_privacy\local\request\userlist($sysctx, 'logstore_database');
 173          $userids = $userlist->get_userids();
 174          $this->assertEmpty($userids);
 175          provider::add_userids_for_context($userlist);
 176          $userids = $userlist->get_userids();
 177          $this->assertEmpty($userids);
 178          // User one should be added (userid).
 179          $this->setUser($u1);
 180          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
 181          $e->trigger();
 182          // User two (userids) and three (relateduserid) should be added.
 183          $this->setUser($u2);
 184          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx, 'relateduserid' => $u3->id]);
 185          $e->trigger();
 186          // The admin user should be added (realuserid).
 187          $this->setAdminUser();
 188          \core\session\manager::loginas($u2->id, context_system::instance());
 189          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
 190          $e->trigger();
 191          // Set off an event in a different context. User 4 should not be returned below.
 192          $this->setUser($u4);
 193          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 194          $e->trigger();
 195  
 196          provider::add_userids_for_context($userlist);
 197          $userids = $userlist->get_userids();
 198          $this->assertCount(4, $userids);
 199          $expectedresult = [$admin->id, $u1->id, $u2->id, $u3->id];
 200          $this->assertEmpty(array_diff($expectedresult, $userids));
 201      }
 202  
 203      public function test_delete_data_for_user() {
 204          global $DB;
 205          $u1 = $this->getDataGenerator()->create_user();
 206          $u2 = $this->getDataGenerator()->create_user();
 207          $c1 = $this->getDataGenerator()->create_course();
 208          $c2 = $this->getDataGenerator()->create_course();
 209          $sysctx = context_system::instance();
 210          $c1ctx = context_course::instance($c1->id);
 211          $c2ctx = context_course::instance($c2->id);
 212  
 213          $this->enable_logging();
 214          $manager = get_log_manager(true);
 215  
 216          // User 1 is the author.
 217          $this->setUser($u1);
 218          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 219          $e->trigger();
 220          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 221          $e->trigger();
 222          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
 223          $e->trigger();
 224  
 225          // User 2 is the author.
 226          $this->setUser($u2);
 227          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 228          $e->trigger();
 229          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
 230          $e->trigger();
 231  
 232          // Confirm data present.
 233          $this->assertTrue($DB->record_exists('logstore_standard_log', ['userid' => $u1->id, 'contextid' => $c1ctx->id]));
 234          $this->assertEquals(3, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
 235          $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
 236  
 237          // Delete all the things!
 238          provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_database', [$c1ctx->id]));
 239          $this->assertFalse($DB->record_exists('logstore_standard_log', ['userid' => $u1->id, 'contextid' => $c1ctx->id]));
 240          $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
 241          $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
 242      }
 243  
 244      public function test_delete_data_for_all_users_in_context() {
 245          global $DB;
 246          $u1 = $this->getDataGenerator()->create_user();
 247          $u2 = $this->getDataGenerator()->create_user();
 248          $c1 = $this->getDataGenerator()->create_course();
 249          $c2 = $this->getDataGenerator()->create_course();
 250          $sysctx = context_system::instance();
 251          $c1ctx = context_course::instance($c1->id);
 252          $c2ctx = context_course::instance($c2->id);
 253  
 254          $this->enable_logging();
 255          $manager = get_log_manager(true);
 256  
 257          // User 1 is the author.
 258          $this->setUser($u1);
 259          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 260          $e->trigger();
 261          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 262          $e->trigger();
 263          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
 264          $e->trigger();
 265  
 266          // User 2 is the author.
 267          $this->setUser($u2);
 268          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 269          $e->trigger();
 270          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx]);
 271          $e->trigger();
 272  
 273          // Confirm data present.
 274          $this->assertTrue($DB->record_exists('logstore_standard_log', ['contextid' => $c1ctx->id]));
 275          $this->assertEquals(3, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
 276          $this->assertEquals(2, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
 277  
 278          // Delete all the things!
 279          provider::delete_data_for_all_users_in_context($c1ctx);
 280          $this->assertFalse($DB->record_exists('logstore_standard_log', ['contextid' => $c1ctx->id]));
 281          $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u1->id]));
 282          $this->assertEquals(1, $DB->count_records('logstore_standard_log', ['userid' => $u2->id]));
 283      }
 284  
 285      /**
 286       * Check that data is removed for the listed users in a given context.
 287       */
 288      public function test_delete_data_for_userlist() {
 289          global $DB;
 290  
 291          $u1 = $this->getDataGenerator()->create_user();
 292          $u2 = $this->getDataGenerator()->create_user();
 293          $u3 = $this->getDataGenerator()->create_user();
 294          $u4 = $this->getDataGenerator()->create_user();
 295  
 296          $course = $this->getDataGenerator()->create_course();
 297          $sysctx = context_system::instance();
 298          $c1ctx = context_course::instance($course->id);
 299  
 300          $this->enable_logging();
 301          $manager = get_log_manager(true);
 302  
 303          $this->setUser($u1);
 304          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
 305          $e->trigger();
 306          $this->setUser($u2);
 307          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
 308          $e->trigger();
 309          $this->setUser($u3);
 310          $e = \logstore_database\event\unittest_executed::create(['context' => $sysctx]);
 311          $e->trigger();
 312          $this->setUser($u4);
 313          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx]);
 314          $e->trigger();
 315  
 316          // Check that four records were created.
 317          $this->assertEquals(4, $DB->count_records('logstore_standard_log'));
 318  
 319          $userlist = new \core_privacy\local\request\approved_userlist($sysctx, 'logstore_database', [$u1->id, $u3->id]);
 320          provider::delete_data_for_userlist($userlist);
 321          // We should have a record for u2 and u4.
 322          $this->assertEquals(2, $DB->count_records('logstore_standard_log'));
 323  
 324          $records = $DB->get_records('logstore_standard_log', ['contextid' => $sysctx->id]);
 325          $this->assertCount(1, $records);
 326          $currentrecord = array_shift($records);
 327          $this->assertEquals($u2->id, $currentrecord->userid);
 328      }
 329  
 330      public function test_export_data_for_user() {
 331          $admin = \core_user::get_user(2);
 332          $u1 = $this->getDataGenerator()->create_user();
 333          $u2 = $this->getDataGenerator()->create_user();
 334          $u3 = $this->getDataGenerator()->create_user();
 335          $u4 = $this->getDataGenerator()->create_user();
 336          $c1 = $this->getDataGenerator()->create_course();
 337          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
 338          $c2 = $this->getDataGenerator()->create_course();
 339          $cm2 = $this->getDataGenerator()->create_module('url', ['course' => $c2]);
 340          $sysctx = context_system::instance();
 341          $c1ctx = context_course::instance($c1->id);
 342          $c2ctx = context_course::instance($c2->id);
 343          $cm1ctx = context_module::instance($cm1->cmid);
 344          $cm2ctx = context_module::instance($cm2->cmid);
 345  
 346          $path = [get_string('privacy:path:logs', 'tool_log'), get_string('pluginname', 'logstore_database')];
 347          $this->enable_logging();
 348          $manager = get_log_manager(true);
 349  
 350          // User 1 is the author.
 351          $this->setUser($u1);
 352          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'other' => ['i' => 0]]);
 353          $e->trigger();
 354  
 355          // User 2 is related.
 356          $this->setUser(0);
 357          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'relateduserid' => $u2->id,
 358              'other' => ['i' => 1]]);
 359          $e->trigger();
 360  
 361          // Admin user masquerades u3, which is related to u4.
 362          $this->setAdminUser();
 363          \core\session\manager::loginas($u3->id, $sysctx);
 364          $e = \logstore_database\event\unittest_executed::create(['context' => $c1ctx, 'relateduserid' => $u4->id,
 365              'other' => ['i' => 2]]);
 366          $e->trigger();
 367  
 368          // Confirm data present for u1.
 369          provider::export_user_data(new approved_contextlist($u1, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
 370          $data = writer::with_context($c2ctx)->get_data($path);
 371          $this->assertEmpty($data);
 372          $data = writer::with_context($c1ctx)->get_data($path);
 373          $this->assertCount(1, $data->logs);
 374          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
 375          $this->assertSame(0, $data->logs[0]['other']['i']);
 376  
 377          // Confirm data present for u2.
 378          writer::reset();
 379          provider::export_user_data(new approved_contextlist($u2, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
 380          $data = writer::with_context($c2ctx)->get_data($path);
 381          $this->assertEmpty($data);
 382          $data = writer::with_context($c1ctx)->get_data($path);
 383          $this->assertCount(1, $data->logs);
 384          $this->assertEquals(transform::yesno(false), $data->logs[0]['author_of_the_action_was_you']);
 385          $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
 386          $this->assertSame(1, $data->logs[0]['other']['i']);
 387  
 388          // Confirm data present for u3.
 389          writer::reset();
 390          provider::export_user_data(new approved_contextlist($u3, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
 391          $data = writer::with_context($c2ctx)->get_data($path);
 392          $this->assertEmpty($data);
 393          $data = writer::with_context($c1ctx)->get_data($path);
 394          $this->assertCount(1, $data->logs);
 395          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
 396          $this->assertEquals(transform::yesno(false), $data->logs[0]['related_user_was_you']);
 397          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
 398          $this->assertEquals(transform::yesno(false), $data->logs[0]['masquerading_user_was_you']);
 399          $this->assertSame(2, $data->logs[0]['other']['i']);
 400  
 401          // Confirm data present for u4.
 402          writer::reset();
 403          provider::export_user_data(new approved_contextlist($u4, 'logstore_database', [$c2ctx->id, $c1ctx->id]));
 404          $data = writer::with_context($c2ctx)->get_data($path);
 405          $this->assertEmpty($data);
 406          $data = writer::with_context($c1ctx)->get_data($path);
 407          $this->assertCount(1, $data->logs);
 408          $this->assertEquals(transform::yesno(false), $data->logs[0]['author_of_the_action_was_you']);
 409          $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
 410          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
 411          $this->assertEquals(transform::yesno(false), $data->logs[0]['masquerading_user_was_you']);
 412          $this->assertSame(2, $data->logs[0]['other']['i']);
 413  
 414          // Add anonymous events.
 415          $this->setUser($u1);
 416          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u2->id,
 417              'anonymous' => true]);
 418          $e->trigger();
 419          $this->setAdminUser();
 420          \core\session\manager::loginas($u3->id, $sysctx);
 421          $e = \logstore_database\event\unittest_executed::create(['context' => $c2ctx, 'relateduserid' => $u4->id,
 422              'anonymous' => true]);
 423          $e->trigger();
 424  
 425          // Confirm data present for u1.
 426          provider::export_user_data(new approved_contextlist($u1, 'logstore_database', [$c2ctx->id]));
 427          $data = writer::with_context($c2ctx)->get_data($path);
 428          $this->assertCount(1, $data->logs);
 429          $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
 430          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
 431  
 432          // Confirm data present for u2.
 433          writer::reset();
 434          provider::export_user_data(new approved_contextlist($u2, 'logstore_database', [$c2ctx->id]));
 435          $data = writer::with_context($c2ctx)->get_data($path);
 436          $this->assertCount(1, $data->logs);
 437          $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
 438          $this->assertArrayNotHasKey('author_of_the_action_was_you', $data->logs[0]);
 439          $this->assertArrayNotHasKey('authorid', $data->logs[0]);
 440          $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
 441  
 442          // Confirm data present for u3.
 443          writer::reset();
 444          provider::export_user_data(new approved_contextlist($u3, 'logstore_database', [$c2ctx->id]));
 445          $data = writer::with_context($c2ctx)->get_data($path);
 446          $this->assertCount(1, $data->logs);
 447          $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
 448          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_you']);
 449          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
 450          $this->assertArrayNotHasKey('masquerading_user_was_you', $data->logs[0]);
 451          $this->assertArrayNotHasKey('masqueradinguserid', $data->logs[0]);
 452  
 453          // Confirm data present for u4.
 454          writer::reset();
 455          provider::export_user_data(new approved_contextlist($u4, 'logstore_database', [$c2ctx->id]));
 456          $data = writer::with_context($c2ctx)->get_data($path);
 457          $this->assertCount(1, $data->logs);
 458          $this->assertEquals(transform::yesno(true), $data->logs[0]['action_was_done_anonymously']);
 459          $this->assertArrayNotHasKey('author_of_the_action_was_you', $data->logs[0]);
 460          $this->assertArrayNotHasKey('authorid', $data->logs[0]);
 461          $this->assertEquals(transform::yesno(true), $data->logs[0]['related_user_was_you']);
 462          $this->assertEquals(transform::yesno(true), $data->logs[0]['author_of_the_action_was_masqueraded']);
 463          $this->assertArrayNotHasKey('masquerading_user_was_you', $data->logs[0]);
 464          $this->assertArrayNotHasKey('masqueradinguserid', $data->logs[0]);
 465      }
 466  
 467      /**
 468       * Assert the content of a context list.
 469       *
 470       * @param contextlist $contextlist The collection.
 471       * @param array $expected List of expected contexts or IDs.
 472       * @return void
 473       */
 474      protected function assert_contextlist_equals($contextlist, array $expected) {
 475          $expectedids = array_map(function($context) {
 476              if (is_object($context)) {
 477                  return $context->id;
 478              }
 479              return $context;
 480          }, $expected);
 481          $contextids = array_map('intval', $contextlist->get_contextids());
 482          sort($contextids);
 483          sort($expectedids);
 484          $this->assertEquals($expectedids, $contextids);
 485      }
 486  
 487      /**
 488       * Enable logging.
 489       *
 490       * @return void
 491       */
 492      protected function enable_logging() {
 493          set_config('enabled_stores', 'logstore_database', 'tool_log');
 494          set_config('buffersize', 0, 'logstore_database');
 495          set_config('logguests', 1, 'logstore_database');
 496          get_log_manager(true);
 497      }
 498  
 499      /**
 500       * Get the contextlist for a user.
 501       *
 502       * @param object $user The user.
 503       * @return contextlist
 504       */
 505      protected function get_contextlist_for_user($user) {
 506          $contextlist = new contextlist();
 507          provider::add_contexts_for_userid($contextlist, $user->id);
 508          return $contextlist;
 509      }
 510  }