Search moodle.org's
Developer Documentation

See Release Notes

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