Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 311 and 402] [Versions 400 and 402] [Versions 401 and 402]

   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   * Unit tests for the editor_atto implementation of the privacy API.
  19   *
  20   * @package    editor_atto
  21   * @category   test
  22   * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  namespace editor_atto\privacy;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  use core_privacy\local\request\writer;
  30  use core_privacy\local\request\approved_contextlist;
  31  use editor_atto\privacy\provider;
  32  use core_privacy\local\request\approved_userlist;
  33  
  34  /**
  35   * Unit tests for the editor_atto implementation of the privacy API.
  36   *
  37   * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class provider_test extends \core_privacy\tests\provider_testcase {
  41      /**
  42       * One test to check fetch and export of all drafts.
  43       */
  44      public function test_fetch_and_exports_drafts() {
  45          global $USER;
  46          $this->resetAfterTest();
  47  
  48          // Create editor drafts in:
  49          // - the system; and
  50          // - a course; and
  51          // - current user context; and
  52          // - another user.
  53  
  54          $systemcontext = \context_system::instance();
  55          $course = $this->getDataGenerator()->create_course();
  56          $coursecontext = \context_course::instance($course->id);
  57  
  58          $usercontextids = [];
  59          $user = $this->getDataGenerator()->create_user();
  60          $this->setUser($user);
  61  
  62          $usercontext = \context_user::instance($user->id);
  63          $usercontextids[] = $usercontext->id;
  64          $usercontextids[] = $systemcontext->id;
  65          $usercontextids[] = $coursecontext->id;
  66  
  67          // Add a fake inline image to the original post.
  68  
  69          $userdraftintro = $this->create_editor_draft($usercontext, $user->id,
  70                  'id_user_intro', 'text for test user at own context');
  71          $userdraftdescription = $this->create_editor_draft($usercontext, $user->id,
  72                  'id_user_description', 'text for test user at own context');
  73          $systemuserdraftintro = $this->create_editor_draft($systemcontext, $user->id,
  74                  'id_system_intro', 'text for test user at system context', 2);
  75          $systemuserdraftdescription = $this->create_editor_draft($systemcontext, $user->id,
  76                  'id_system_description', 'text for test user at system context', 4);
  77          $coursedraftintro = $this->create_editor_draft($coursecontext, $user->id,
  78                  'id_course_intro', 'text for test user at course context');
  79          $coursedraftdescription = $this->create_editor_draft($coursecontext, $user->id,
  80                  'id_course_description', 'text for test user at course context');
  81  
  82          // Create some data as the other user too.
  83          $otherusercontextids = [];
  84          $otheruser = $this->getDataGenerator()->create_user();
  85          $this->setUser($otheruser);
  86  
  87          $otherusercontext = \context_user::instance($otheruser->id);
  88          $otherusercontextids[] = $otherusercontext->id;
  89          $otherusercontextids[] = $systemcontext->id;
  90          $otherusercontextids[] = $coursecontext->id;
  91  
  92          $otheruserdraftintro = $this->create_editor_draft($otherusercontext, $otheruser->id,
  93                  'id_user_intro', 'text for other user at own context');
  94          $otheruserdraftdescription = $this->create_editor_draft($otherusercontext, $otheruser->id,
  95                  'id_user_description', 'text for other user at own context');
  96          $systemotheruserdraftintro = $this->create_editor_draft($systemcontext, $otheruser->id,
  97                  'id_system_intro', 'text for other user at system context');
  98          $systemotheruserdraftdescription = $this->create_editor_draft($systemcontext, $otheruser->id,
  99                  'id_system_description', 'text for other user at system context');
 100          $courseotheruserdraftintro = $this->create_editor_draft($coursecontext, $otheruser->id,
 101                  'id_course_intro', 'text for other user at course context');
 102          $courseotheruserdraftdescription = $this->create_editor_draft($coursecontext, $otheruser->id,
 103                  'id_course_description', 'text for other user at course context');
 104  
 105          // Test as the original user.
 106          // Get all context data for the original user.
 107          $this->setUser($user);
 108          $contextlist = provider::get_contexts_for_userid($user->id);
 109  
 110          // There are three contexts in the list.
 111          $this->assertCount(3, $contextlist);
 112  
 113          // Check the list against the expected list of contexts.
 114          foreach ($contextlist as $context) {
 115              $this->assertContains($context->id, $usercontextids);
 116          }
 117  
 118          // Export the data for the system context.
 119          // There should be two.
 120          $this->export_context_data_for_user($user->id, $systemcontext, 'editor_atto');
 121          /** @var \core_privacy\tests\request\content_writer $writer */
 122          $writer = \core_privacy\local\request\writer::with_context($systemcontext);
 123          $this->assertTrue($writer->has_any_data());
 124  
 125          $subcontextbase = [get_string('autosaves', 'editor_atto')];
 126  
 127          // There should be an intro and description.
 128          $intro = $writer->get_data(array_merge($subcontextbase, [$systemuserdraftintro->id]));
 129          $fs = get_file_storage();
 130          $this->assertEquals(
 131                  format_text($systemuserdraftintro->drafttext, FORMAT_HTML, provider::get_filter_options()),
 132                  $intro->drafttext
 133              );
 134          $this->assertCount(2, $writer->get_files(array_merge($subcontextbase, [$systemuserdraftintro->id])));
 135  
 136          $description = $writer->get_data(array_merge($subcontextbase, [$systemuserdraftdescription->id]));
 137          $this->assertEquals(
 138                  format_text($systemuserdraftdescription->drafttext, FORMAT_HTML, provider::get_filter_options()),
 139                  $description->drafttext
 140              );
 141          $this->assertCount(4, $writer->get_files(array_merge($subcontextbase, [$systemuserdraftdescription->id])));
 142      }
 143  
 144      /**
 145       * Test delete_for_all_users_in_context.
 146       */
 147      public function test_delete_for_all_users_in_context() {
 148          global $USER, $DB;
 149          $this->resetAfterTest();
 150  
 151          // Create editor drafts in:
 152          // - the system; and
 153          // - a course; and
 154          // - current user context; and
 155          // - another user.
 156  
 157          $systemcontext = \context_system::instance();
 158          $course = $this->getDataGenerator()->create_course();
 159          $coursecontext = \context_course::instance($course->id);
 160  
 161          $usercontextids = [];
 162          $user = $this->getDataGenerator()->create_user();
 163          $this->setUser($user);
 164  
 165          $usercontext = \context_user::instance($user->id);
 166          $usercontextids[] = $usercontext->id;
 167          $usercontextids[] = $systemcontext->id;
 168          $usercontextids[] = $coursecontext->id;
 169  
 170          // Add a fake inline image to the original post.
 171  
 172          $userdraftintro = $this->create_editor_draft($usercontext, $user->id,
 173                  'id_user_intro', 'text for test user at own context');
 174          $userdraftdescription = $this->create_editor_draft($usercontext, $user->id,
 175                  'id_user_description', 'text for test user at own context');
 176          $systemuserdraftintro = $this->create_editor_draft($systemcontext, $user->id,
 177                  'id_system_intro', 'text for test user at system context', 2);
 178          $systemuserdraftdescription = $this->create_editor_draft($systemcontext, $user->id,
 179                  'id_system_description', 'text for test user at system context', 4);
 180          $coursedraftintro = $this->create_editor_draft($coursecontext, $user->id,
 181                  'id_course_intro', 'text for test user at course context');
 182          $coursedraftdescription = $this->create_editor_draft($coursecontext, $user->id,
 183                  'id_course_description', 'text for test user at course context');
 184  
 185          // Create some data as the other user too.
 186          $otherusercontextids = [];
 187          $otheruser = $this->getDataGenerator()->create_user();
 188          $this->setUser($otheruser);
 189  
 190          $otherusercontext = \context_user::instance($otheruser->id);
 191          $otherusercontextids[] = $otherusercontext->id;
 192          $otherusercontextids[] = $systemcontext->id;
 193          $otherusercontextids[] = $coursecontext->id;
 194  
 195          $otheruserdraftintro = $this->create_editor_draft($otherusercontext, $otheruser->id,
 196                  'id_user_intro', 'text for other user at own context');
 197          $otheruserdraftdescription = $this->create_editor_draft($otherusercontext, $otheruser->id,
 198                  'id_user_description', 'text for other user at own context');
 199          $systemotheruserdraftintro = $this->create_editor_draft($systemcontext, $otheruser->id,
 200                  'id_system_intro', 'text for other user at system context');
 201          $systemotheruserdraftdescription = $this->create_editor_draft($systemcontext, $otheruser->id,
 202                  'id_system_description', 'text for other user at system context');
 203          $courseotheruserdraftintro = $this->create_editor_draft($coursecontext, $otheruser->id,
 204                  'id_course_intro', 'text for other user at course context');
 205          $courseotheruserdraftdescription = $this->create_editor_draft($coursecontext, $otheruser->id,
 206                  'id_course_description', 'text for other user at course context');
 207  
 208          // Test deletion of the user context.
 209          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 210          provider::delete_data_for_all_users_in_context($usercontext);
 211          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 212  
 213          // No other contexts should be removed.
 214          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 215          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 216          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 217  
 218          // Test deletion of the course contexts.
 219          provider::delete_data_for_all_users_in_context($coursecontext);
 220          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 221          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 222          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 223  
 224          // Test deletion of the system contexts.
 225          provider::delete_data_for_all_users_in_context($systemcontext);
 226          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 227          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 228      }
 229  
 230      /**
 231       * Test delete_for_all_users_in_context.
 232       */
 233      public function test_delete_for_user_in_contexts() {
 234          global $USER, $DB;
 235          $this->resetAfterTest();
 236  
 237          // Create editor drafts in:
 238          // - the system; and
 239          // - a course; and
 240          // - current user context; and
 241          // - another user.
 242  
 243          $systemcontext = \context_system::instance();
 244          $course = $this->getDataGenerator()->create_course();
 245          $coursecontext = \context_course::instance($course->id);
 246  
 247          $usercontextids = [];
 248          $user = $this->getDataGenerator()->create_user();
 249          $this->setUser($user);
 250  
 251          $usercontext = \context_user::instance($user->id);
 252          $usercontextids[] = $usercontext->id;
 253          $usercontextids[] = $systemcontext->id;
 254          $usercontextids[] = $coursecontext->id;
 255  
 256          // Add a fake inline image to the original post.
 257  
 258          $userdraftintro = $this->create_editor_draft($usercontext, $user->id,
 259                  'id_user_intro', 'text for test user at own context');
 260          $userdraftdescription = $this->create_editor_draft($usercontext, $user->id,
 261                  'id_user_description', 'text for test user at own context');
 262          $systemuserdraftintro = $this->create_editor_draft($systemcontext, $user->id,
 263                  'id_system_intro', 'text for test user at system context', 2);
 264          $systemuserdraftdescription = $this->create_editor_draft($systemcontext, $user->id,
 265                  'id_system_description', 'text for test user at system context', 4);
 266          $coursedraftintro = $this->create_editor_draft($coursecontext, $user->id,
 267                  'id_course_intro', 'text for test user at course context');
 268          $coursedraftdescription = $this->create_editor_draft($coursecontext, $user->id,
 269                  'id_course_description', 'text for test user at course context');
 270  
 271          // Create some data as the other user too.
 272          $otherusercontextids = [];
 273          $otheruser = $this->getDataGenerator()->create_user();
 274          $this->setUser($otheruser);
 275  
 276          $otherusercontext = \context_user::instance($otheruser->id);
 277          $otherusercontextids[] = $otherusercontext->id;
 278          $otherusercontextids[] = $systemcontext->id;
 279          $otherusercontextids[] = $coursecontext->id;
 280  
 281          $otheruserdraftintro = $this->create_editor_draft($otherusercontext, $otheruser->id,
 282                  'id_user_intro', 'text for other user at own context');
 283          $otheruserdraftdescription = $this->create_editor_draft($otherusercontext, $otheruser->id,
 284                  'id_user_description', 'text for other user at own context');
 285          $systemotheruserdraftintro = $this->create_editor_draft($systemcontext, $otheruser->id,
 286                  'id_system_intro', 'text for other user at system context');
 287          $systemotheruserdraftdescription = $this->create_editor_draft($systemcontext, $otheruser->id,
 288                  'id_system_description', 'text for other user at system context');
 289          $courseotheruserdraftintro = $this->create_editor_draft($coursecontext, $otheruser->id,
 290                  'id_course_intro', 'text for other user at course context');
 291          $courseotheruserdraftdescription = $this->create_editor_draft($coursecontext, $otheruser->id,
 292                  'id_course_description', 'text for other user at course context');
 293  
 294          // Test deletion of all data for user in usercontext only.
 295          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 296              \core_user::get_user($user->id),
 297              'editor_atto',
 298              [$usercontext->id]
 299          );
 300          provider::delete_data_for_user($contextlist);
 301          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 302  
 303          // No other contexts should be removed.
 304          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 305          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 306          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 307  
 308          // Test deletion of all data for user in course and system.
 309          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 310              \core_user::get_user($user->id),
 311              'editor_atto',
 312              [$coursecontext->id, $systemcontext->id]
 313          );
 314          provider::delete_data_for_user($contextlist);
 315          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 316          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 317          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 318          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 319  
 320          // Data for the other user should remain.
 321          $this->assertCount(2, $DB->get_records('editor_atto_autosave', [
 322              'contextid' => $coursecontext->id,
 323              'userid' => $otheruser->id,
 324          ]));
 325  
 326          $this->assertCount(2, $DB->get_records('editor_atto_autosave', [
 327              'contextid' => $systemcontext->id,
 328              'userid' => $otheruser->id,
 329          ]));
 330      }
 331  
 332      /**
 333       * Test that user data with different contexts is fetched.
 334       */
 335      public function test_get_users_in_context() {
 336          $this->resetAfterTest();
 337  
 338          $component = 'editor_atto';
 339  
 340          // Create editor drafts in:
 341          // - the system; and
 342          // - a course; and
 343          // - current user context; and
 344          // - another user.
 345  
 346          $systemcontext = \context_system::instance();
 347          // Create a course.
 348          $course = $this->getDataGenerator()->create_course();
 349          $coursecontext = \context_course::instance($course->id);
 350  
 351          // Create a user.
 352          $user = $this->getDataGenerator()->create_user();
 353          $usercontext = \context_user::instance($user->id);
 354          $this->setUser($user);
 355  
 356          // Add a fake inline image to the original post.
 357          $this->create_editor_draft($usercontext, $user->id,
 358                  'id_user_intro', 'text for test user at own context');
 359          $this->create_editor_draft($systemcontext, $user->id,
 360              'id_system_intro', 'text for test user at system context', 2);
 361          $this->create_editor_draft($systemcontext, $user->id,
 362              'id_system_description', 'text for test user at system context', 4);
 363          $this->create_editor_draft($coursecontext, $user->id,
 364              'id_course_intro', 'text for test user at course context');
 365  
 366          // Create user2.
 367          $user2 = $this->getDataGenerator()->create_user();
 368          $this->setUser($user2);
 369  
 370          $this->create_editor_draft($coursecontext, $user2->id,
 371              'id_course_description', 'text for test user2 at course context');
 372  
 373          // The list of users in usercontext should return user.
 374          $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
 375          provider::get_users_in_context($userlist);
 376          $this->assertCount(1, $userlist);
 377          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 378  
 379          // The list of users in systemcontext should return user.
 380          $userlist = new \core_privacy\local\request\userlist($systemcontext, $component);
 381          provider::get_users_in_context($userlist);
 382          $this->assertCount(1, $userlist);
 383          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 384  
 385          // The list of users in coursecontext should return user and user2.
 386          $userlist = new \core_privacy\local\request\userlist($coursecontext, $component);
 387          provider::get_users_in_context($userlist);
 388          $this->assertCount(2, $userlist);
 389          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 390          $this->assertTrue(in_array($user2->id, $userlist->get_userids()));
 391      }
 392  
 393      /**
 394       * Test that data for users in approved userlist is deleted.
 395       */
 396      public function test_delete_data_for_users() {
 397          $this->resetAfterTest();
 398  
 399          $component = 'editor_atto';
 400  
 401          // Create editor drafts in:
 402          // - the system; and
 403          // - a course; and
 404          // - current user context; and
 405          // - another user.
 406  
 407          $systemcontext = \context_system::instance();
 408          // Create a course.
 409          $course = $this->getDataGenerator()->create_course();
 410          $coursecontext = \context_course::instance($course->id);
 411  
 412          // Create a user.
 413          $user = $this->getDataGenerator()->create_user();
 414          $usercontext = \context_user::instance($user->id);
 415          $this->setUser($user);
 416  
 417          // Add a fake inline image to the original post.
 418          $this->create_editor_draft($usercontext, $user->id,
 419              'id_user_intro', 'text for test user at own context');
 420          $this->create_editor_draft($usercontext, $user->id,
 421              'id_user_description', 'text for test user at own context');
 422          $this->create_editor_draft($systemcontext, $user->id,
 423              'id_system_intro', 'text for test user at system context', 2);
 424          $this->create_editor_draft($systemcontext, $user->id,
 425              'id_system_description', 'text for test user at system context', 4);
 426          $this->create_editor_draft($coursecontext, $user->id,
 427              'id_course_intro', 'text for test user at course context');
 428          $this->create_editor_draft($coursecontext, $user->id,
 429              'id_course_description', 'text for test user at course context');
 430  
 431          // Create some data as the other user too.
 432          $otheruser = $this->getDataGenerator()->create_user();
 433          $otherusercontext = \context_user::instance($otheruser->id);
 434          $this->setUser($otheruser);
 435  
 436          $this->create_editor_draft($otherusercontext, $otheruser->id,
 437              'id_user_intro', 'text for other user at own context');
 438          $this->create_editor_draft($otherusercontext, $otheruser->id,
 439              'id_user_description', 'text for other user at own context');
 440          $this->create_editor_draft($systemcontext, $otheruser->id,
 441              'id_system_intro', 'text for other user at system context');
 442          $this->create_editor_draft($systemcontext, $otheruser->id,
 443              'id_system_description', 'text for other user at system context');
 444          $this->create_editor_draft($coursecontext, $otheruser->id,
 445              'id_course_intro', 'text for other user at course context');
 446          $this->create_editor_draft($coursecontext, $otheruser->id,
 447              'id_course_description', 'text for other user at course context');
 448  
 449          // The list of users for usercontext should return user.
 450          $userlist1 = new \core_privacy\local\request\userlist($usercontext, $component);
 451          provider::get_users_in_context($userlist1);
 452          $this->assertCount(1, $userlist1);
 453          $this->assertTrue(in_array($user->id, $userlist1->get_userids()));
 454  
 455          // The list of users for otherusercontext should return otheruser.
 456          $userlist2 = new \core_privacy\local\request\userlist($otherusercontext, $component);
 457          provider::get_users_in_context($userlist2);
 458          $this->assertCount(1, $userlist2);
 459          $this->assertTrue(in_array($otheruser->id, $userlist2->get_userids()));
 460  
 461          // Add userlist1 to the approved user list.
 462          $approvedlist = new approved_userlist($usercontext, $component, $userlist1->get_userids());
 463          // Delete user data using delete_data_for_user for usercontext.
 464          provider::delete_data_for_users($approvedlist);
 465  
 466          // Re-fetch users in usercontext - The user list should now be empty.
 467          $userlist1 = new \core_privacy\local\request\userlist($usercontext, $component);
 468          provider::get_users_in_context($userlist1);
 469          $this->assertCount(0, $userlist1);
 470          // Re-fetch users in otherusercontext - The user list should not be empty (otheruser).
 471          $userlist2 = new \core_privacy\local\request\userlist($otherusercontext, $component);
 472          provider::get_users_in_context($userlist2);
 473          $this->assertCount(1, $userlist2);
 474          $this->assertTrue(in_array($otheruser->id, $userlist2->get_userids()));
 475  
 476          // The list of users for systemcontext should return user and otheruser.
 477          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
 478          provider::get_users_in_context($userlist3);
 479          $this->assertCount(2, $userlist3);
 480          $this->assertTrue(in_array($user->id, $userlist3->get_userids()));
 481          $this->assertTrue(in_array($otheruser->id, $userlist3->get_userids()));
 482  
 483          // Add $userlist3 to the approved user list in the system context.
 484          $approvedlist = new approved_userlist($systemcontext, $component, $userlist3->get_userids());
 485          // Delete user and otheruser data using delete_data_for_user.
 486          provider::delete_data_for_users($approvedlist);
 487  
 488          // Re-fetch users in systemcontext - The user list should be empty.
 489          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
 490          provider::get_users_in_context($userlist3);
 491          $this->assertCount(0, $userlist3);
 492  
 493          // The list of users for coursecontext should return user and otheruser.
 494          $userlist4 = new \core_privacy\local\request\userlist($coursecontext, $component);
 495          provider::get_users_in_context($userlist4);
 496          $this->assertCount(2, $userlist4);
 497          $this->assertTrue(in_array($user->id, $userlist4->get_userids()));
 498          $this->assertTrue(in_array($otheruser->id, $userlist4->get_userids()));
 499  
 500          // Add user to the approved user list in the course context.
 501          $approvedlist = new approved_userlist($coursecontext, $component, [$user->id]);
 502          // Delete user data using delete_data_for_user.
 503          provider::delete_data_for_users($approvedlist);
 504  
 505          // Re-fetch users in coursecontext - The user list should return otheruser.
 506          $userlist4 = new \core_privacy\local\request\userlist($coursecontext, $component);
 507          provider::get_users_in_context($userlist4);
 508          $this->assertCount(1, $userlist4);
 509          $this->assertTrue(in_array($otheruser->id, $userlist4->get_userids()));
 510      }
 511  
 512      /**
 513       * Test fetch and delete when another user has editted a draft in your
 514       * user context. Edge case.
 515       */
 516      public function test_another_user_edits_you() {
 517          global $USER, $DB;
 518          $this->resetAfterTest();
 519  
 520          $user = $this->getDataGenerator()->create_user();
 521          $usercontext = \context_user::instance($user->id);
 522          $otheruser = $this->getDataGenerator()->create_user();
 523          $otherusercontext = \context_user::instance($otheruser->id);
 524          $this->setUser($user);
 525  
 526          $userdraftintro = $this->create_editor_draft($usercontext, $otheruser->id,
 527                  'id_user_intro', 'text for test user at other context');
 528  
 529          // Test as the owning user.
 530          $this->setUser($user);
 531          $contextlist = provider::get_contexts_for_userid($user->id);
 532          $contexts = $contextlist->get_contexts();
 533          $this->assertCount(1, $contexts);
 534          $firstcontext = reset($contexts);
 535          $this->assertEquals($usercontext, $firstcontext);
 536  
 537          // Should have the data.
 538          $this->export_context_data_for_user($user->id, $usercontext, 'editor_atto');
 539          /** @var \core_privacy\tests\request\content_writer $writer */
 540          $writer = \core_privacy\local\request\writer::with_context($usercontext);
 541          $this->assertTrue($writer->has_any_data());
 542  
 543          $subcontext = [
 544              get_string('autosaves', 'editor_atto'),
 545              $userdraftintro->id,
 546          ];
 547          $data = $writer->get_data($subcontext);
 548          $this->assertEquals(\core_privacy\local\request\transform::user($otheruser->id), $data->author);
 549  
 550          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 551              \core_user::get_user($user->id),
 552              'editor_atto',
 553              [$usercontext->id]
 554          );
 555  
 556  
 557          // Deleting for this context should _not_ delete as the user does not own this draft (crazy edge case, remember).
 558          provider::delete_data_for_user($contextlist);
 559          $records = $DB->get_records('editor_atto_autosave');
 560          $this->assertNotEmpty($records);
 561          $this->assertCount(1, $records);
 562          $firstrecord = reset($records);
 563          $this->assertEquals($userdraftintro->id, $firstrecord->id);
 564      }
 565  
 566      /**
 567       * Test fetch and delete when you have edited another user's context.
 568       */
 569      public function test_another_you_edit_different_user() {
 570          global $USER, $DB;
 571          $this->resetAfterTest();
 572  
 573          $user = $this->getDataGenerator()->create_user();
 574          $usercontext = \context_user::instance($user->id);
 575          $otheruser = $this->getDataGenerator()->create_user();
 576          $otherusercontext = \context_user::instance($otheruser->id);
 577          $this->setUser($user);
 578  
 579          $userdraftintro = $this->create_editor_draft($otherusercontext, $user->id,
 580                  'id_user_intro', 'text for other user you just edited.');
 581  
 582          // Test as the context owner.
 583          $this->setUser($user);
 584          $contextlist = provider::get_contexts_for_userid($user->id);
 585          $contexts = $contextlist->get_contexts();
 586          $this->assertCount(1, $contexts);
 587          $firstcontext = reset($contexts);
 588          $this->assertEquals($otherusercontext, $firstcontext);
 589  
 590          // Should have the data.
 591          $this->export_context_data_for_user($user->id, $otherusercontext, 'editor_atto');
 592          /** @var \core_privacy\tests\request\content_writer $writer */
 593          $writer = \core_privacy\local\request\writer::with_context($otherusercontext);
 594          $this->assertTrue($writer->has_any_data());
 595  
 596          $subcontext = [
 597              get_string('autosaves', 'editor_atto'),
 598              $userdraftintro->id,
 599          ];
 600          $data = $writer->get_data($subcontext);
 601          $this->assertFalse(isset($data->author));
 602  
 603          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 604              \core_user::get_user($user->id),
 605              'editor_atto',
 606              [$otherusercontext->id]
 607          );
 608          provider::delete_data_for_user($contextlist);
 609          $this->assertEmpty($DB->get_records('editor_atto_autosave'));
 610      }
 611  
 612     /**
 613       * Create an editor draft.
 614       *
 615       * @param   \context    $context The context to create the draft for.
 616       * @param   int         $userid The ID to create the draft for.
 617       * @param   string      $elementid The elementid for the editor.
 618       * @param   string      $text The text to write.
 619       * @param   int         $filecount The number of files to create.
 620       * @return  \stdClass   The editor draft.
 621       */
 622      protected function create_editor_draft(\context $context, $userid, $elementid, $text, $filecount = 0) {
 623          global $DB;
 624  
 625          $draftid = file_get_unused_draft_itemid();
 626          $fs = get_file_storage();
 627  
 628          for ($i = 0; $i < $filecount; $i++) {
 629              $fs->create_file_from_string([
 630                      'contextid' => $context->id,
 631                      'component' => 'user',
 632                      'filearea'  => 'draft',
 633                      'itemid'    => $draftid,
 634                      'filepath'  => '/',
 635                      'filename'  => "example_{$i}.txt",
 636                  ],
 637              "Awesome example of a text file with id {$i} for {$context->id} and {$elementid}");
 638          }
 639  
 640          $id = $DB->insert_record('editor_atto_autosave', (object) [
 641                  'elementid' => $elementid,
 642                  'contextid' => $context->id,
 643                  'userid' => $userid,
 644                  'drafttext' => $text,
 645                  'draftid' => $draftid,
 646                  'pageinstance' => 'example_page_instance_' . rand(1, 1000),
 647                  'timemodified' => time(),
 648  
 649                  // Page hash doesn't matter for our purposes.
 650                  'pagehash' => sha1("{$userid}/{$context->id}/{$elementid}/{$draftid}"),
 651              ]);
 652  
 653          return $DB->get_record('editor_atto_autosave', ['id' => $id]);
 654      }
 655  }