Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * 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          $writer = \core_privacy\local\request\writer::with_context($systemcontext);
 122          $this->assertTrue($writer->has_any_data());
 123  
 124          $subcontextbase = [get_string('autosaves', 'editor_atto')];
 125  
 126          // There should be an intro and description.
 127          $intro = $writer->get_data(array_merge($subcontextbase, [$systemuserdraftintro->id]));
 128          $fs = get_file_storage();
 129          $this->assertEquals(
 130                  format_text($systemuserdraftintro->drafttext, FORMAT_HTML, provider::get_filter_options()),
 131                  $intro->drafttext
 132              );
 133          $this->assertCount(2, $writer->get_files(array_merge($subcontextbase, [$systemuserdraftintro->id])));
 134  
 135          $description = $writer->get_data(array_merge($subcontextbase, [$systemuserdraftdescription->id]));
 136          $this->assertEquals(
 137                  format_text($systemuserdraftdescription->drafttext, FORMAT_HTML, provider::get_filter_options()),
 138                  $description->drafttext
 139              );
 140          $this->assertCount(4, $writer->get_files(array_merge($subcontextbase, [$systemuserdraftdescription->id])));
 141      }
 142  
 143      /**
 144       * Test delete_for_all_users_in_context.
 145       */
 146      public function test_delete_for_all_users_in_context() {
 147          global $USER, $DB;
 148          $this->resetAfterTest();
 149  
 150          // Create editor drafts in:
 151          // - the system; and
 152          // - a course; and
 153          // - current user context; and
 154          // - another user.
 155  
 156          $systemcontext = \context_system::instance();
 157          $course = $this->getDataGenerator()->create_course();
 158          $coursecontext = \context_course::instance($course->id);
 159  
 160          $usercontextids = [];
 161          $user = $this->getDataGenerator()->create_user();
 162          $this->setUser($user);
 163  
 164          $usercontext = \context_user::instance($user->id);
 165          $usercontextids[] = $usercontext->id;
 166          $usercontextids[] = $systemcontext->id;
 167          $usercontextids[] = $coursecontext->id;
 168  
 169          // Add a fake inline image to the original post.
 170  
 171          $userdraftintro = $this->create_editor_draft($usercontext, $user->id,
 172                  'id_user_intro', 'text for test user at own context');
 173          $userdraftdescription = $this->create_editor_draft($usercontext, $user->id,
 174                  'id_user_description', 'text for test user at own context');
 175          $systemuserdraftintro = $this->create_editor_draft($systemcontext, $user->id,
 176                  'id_system_intro', 'text for test user at system context', 2);
 177          $systemuserdraftdescription = $this->create_editor_draft($systemcontext, $user->id,
 178                  'id_system_description', 'text for test user at system context', 4);
 179          $coursedraftintro = $this->create_editor_draft($coursecontext, $user->id,
 180                  'id_course_intro', 'text for test user at course context');
 181          $coursedraftdescription = $this->create_editor_draft($coursecontext, $user->id,
 182                  'id_course_description', 'text for test user at course context');
 183  
 184          // Create some data as the other user too.
 185          $otherusercontextids = [];
 186          $otheruser = $this->getDataGenerator()->create_user();
 187          $this->setUser($otheruser);
 188  
 189          $otherusercontext = \context_user::instance($otheruser->id);
 190          $otherusercontextids[] = $otherusercontext->id;
 191          $otherusercontextids[] = $systemcontext->id;
 192          $otherusercontextids[] = $coursecontext->id;
 193  
 194          $otheruserdraftintro = $this->create_editor_draft($otherusercontext, $otheruser->id,
 195                  'id_user_intro', 'text for other user at own context');
 196          $otheruserdraftdescription = $this->create_editor_draft($otherusercontext, $otheruser->id,
 197                  'id_user_description', 'text for other user at own context');
 198          $systemotheruserdraftintro = $this->create_editor_draft($systemcontext, $otheruser->id,
 199                  'id_system_intro', 'text for other user at system context');
 200          $systemotheruserdraftdescription = $this->create_editor_draft($systemcontext, $otheruser->id,
 201                  'id_system_description', 'text for other user at system context');
 202          $courseotheruserdraftintro = $this->create_editor_draft($coursecontext, $otheruser->id,
 203                  'id_course_intro', 'text for other user at course context');
 204          $courseotheruserdraftdescription = $this->create_editor_draft($coursecontext, $otheruser->id,
 205                  'id_course_description', 'text for other user at course context');
 206  
 207          // Test deletion of the user context.
 208          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 209          provider::delete_data_for_all_users_in_context($usercontext);
 210          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 211  
 212          // No other contexts should be removed.
 213          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 214          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 215          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 216  
 217          // Test deletion of the course contexts.
 218          provider::delete_data_for_all_users_in_context($coursecontext);
 219          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 220          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 221          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 222  
 223          // Test deletion of the system contexts.
 224          provider::delete_data_for_all_users_in_context($systemcontext);
 225          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 226          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 227      }
 228  
 229      /**
 230       * Test delete_for_all_users_in_context.
 231       */
 232      public function test_delete_for_user_in_contexts() {
 233          global $USER, $DB;
 234          $this->resetAfterTest();
 235  
 236          // Create editor drafts in:
 237          // - the system; and
 238          // - a course; and
 239          // - current user context; and
 240          // - another user.
 241  
 242          $systemcontext = \context_system::instance();
 243          $course = $this->getDataGenerator()->create_course();
 244          $coursecontext = \context_course::instance($course->id);
 245  
 246          $usercontextids = [];
 247          $user = $this->getDataGenerator()->create_user();
 248          $this->setUser($user);
 249  
 250          $usercontext = \context_user::instance($user->id);
 251          $usercontextids[] = $usercontext->id;
 252          $usercontextids[] = $systemcontext->id;
 253          $usercontextids[] = $coursecontext->id;
 254  
 255          // Add a fake inline image to the original post.
 256  
 257          $userdraftintro = $this->create_editor_draft($usercontext, $user->id,
 258                  'id_user_intro', 'text for test user at own context');
 259          $userdraftdescription = $this->create_editor_draft($usercontext, $user->id,
 260                  'id_user_description', 'text for test user at own context');
 261          $systemuserdraftintro = $this->create_editor_draft($systemcontext, $user->id,
 262                  'id_system_intro', 'text for test user at system context', 2);
 263          $systemuserdraftdescription = $this->create_editor_draft($systemcontext, $user->id,
 264                  'id_system_description', 'text for test user at system context', 4);
 265          $coursedraftintro = $this->create_editor_draft($coursecontext, $user->id,
 266                  'id_course_intro', 'text for test user at course context');
 267          $coursedraftdescription = $this->create_editor_draft($coursecontext, $user->id,
 268                  'id_course_description', 'text for test user at course context');
 269  
 270          // Create some data as the other user too.
 271          $otherusercontextids = [];
 272          $otheruser = $this->getDataGenerator()->create_user();
 273          $this->setUser($otheruser);
 274  
 275          $otherusercontext = \context_user::instance($otheruser->id);
 276          $otherusercontextids[] = $otherusercontext->id;
 277          $otherusercontextids[] = $systemcontext->id;
 278          $otherusercontextids[] = $coursecontext->id;
 279  
 280          $otheruserdraftintro = $this->create_editor_draft($otherusercontext, $otheruser->id,
 281                  'id_user_intro', 'text for other user at own context');
 282          $otheruserdraftdescription = $this->create_editor_draft($otherusercontext, $otheruser->id,
 283                  'id_user_description', 'text for other user at own context');
 284          $systemotheruserdraftintro = $this->create_editor_draft($systemcontext, $otheruser->id,
 285                  'id_system_intro', 'text for other user at system context');
 286          $systemotheruserdraftdescription = $this->create_editor_draft($systemcontext, $otheruser->id,
 287                  'id_system_description', 'text for other user at system context');
 288          $courseotheruserdraftintro = $this->create_editor_draft($coursecontext, $otheruser->id,
 289                  'id_course_intro', 'text for other user at course context');
 290          $courseotheruserdraftdescription = $this->create_editor_draft($coursecontext, $otheruser->id,
 291                  'id_course_description', 'text for other user at course context');
 292  
 293          // Test deletion of all data for user in usercontext only.
 294          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 295              \core_user::get_user($user->id),
 296              'editor_atto',
 297              [$usercontext->id]
 298          );
 299          provider::delete_data_for_user($contextlist);
 300          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 301  
 302          // No other contexts should be removed.
 303          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 304          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 305          $this->assertCount(4, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 306  
 307          // Test deletion of all data for user in course and system.
 308          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 309              \core_user::get_user($user->id),
 310              'editor_atto',
 311              [$coursecontext->id, $systemcontext->id]
 312          );
 313          provider::delete_data_for_user($contextlist);
 314          $this->assertCount(0, $DB->get_records('editor_atto_autosave', ['contextid' => $usercontext->id]));
 315          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $otherusercontext->id]));
 316          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $systemcontext->id]));
 317          $this->assertCount(2, $DB->get_records('editor_atto_autosave', ['contextid' => $coursecontext->id]));
 318  
 319          // Data for the other user should remain.
 320          $this->assertCount(2, $DB->get_records('editor_atto_autosave', [
 321              'contextid' => $coursecontext->id,
 322              'userid' => $otheruser->id,
 323          ]));
 324  
 325          $this->assertCount(2, $DB->get_records('editor_atto_autosave', [
 326              'contextid' => $systemcontext->id,
 327              'userid' => $otheruser->id,
 328          ]));
 329      }
 330  
 331      /**
 332       * Test that user data with different contexts is fetched.
 333       */
 334      public function test_get_users_in_context() {
 335          $this->resetAfterTest();
 336  
 337          $component = 'editor_atto';
 338  
 339          // Create editor drafts in:
 340          // - the system; and
 341          // - a course; and
 342          // - current user context; and
 343          // - another user.
 344  
 345          $systemcontext = \context_system::instance();
 346          // Create a course.
 347          $course = $this->getDataGenerator()->create_course();
 348          $coursecontext = \context_course::instance($course->id);
 349  
 350          // Create a user.
 351          $user = $this->getDataGenerator()->create_user();
 352          $usercontext = \context_user::instance($user->id);
 353          $this->setUser($user);
 354  
 355          // Add a fake inline image to the original post.
 356          $this->create_editor_draft($usercontext, $user->id,
 357                  'id_user_intro', 'text for test user at own context');
 358          $this->create_editor_draft($systemcontext, $user->id,
 359              'id_system_intro', 'text for test user at system context', 2);
 360          $this->create_editor_draft($systemcontext, $user->id,
 361              'id_system_description', 'text for test user at system context', 4);
 362          $this->create_editor_draft($coursecontext, $user->id,
 363              'id_course_intro', 'text for test user at course context');
 364  
 365          // Create user2.
 366          $user2 = $this->getDataGenerator()->create_user();
 367          $this->setUser($user2);
 368  
 369          $this->create_editor_draft($coursecontext, $user2->id,
 370              'id_course_description', 'text for test user2 at course context');
 371  
 372          // The list of users in usercontext should return user.
 373          $userlist = new \core_privacy\local\request\userlist($usercontext, $component);
 374          provider::get_users_in_context($userlist);
 375          $this->assertCount(1, $userlist);
 376          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 377  
 378          // The list of users in systemcontext should return user.
 379          $userlist = new \core_privacy\local\request\userlist($systemcontext, $component);
 380          provider::get_users_in_context($userlist);
 381          $this->assertCount(1, $userlist);
 382          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 383  
 384          // The list of users in coursecontext should return user and user2.
 385          $userlist = new \core_privacy\local\request\userlist($coursecontext, $component);
 386          provider::get_users_in_context($userlist);
 387          $this->assertCount(2, $userlist);
 388          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 389          $this->assertTrue(in_array($user2->id, $userlist->get_userids()));
 390      }
 391  
 392      /**
 393       * Test that data for users in approved userlist is deleted.
 394       */
 395      public function test_delete_data_for_users() {
 396          $this->resetAfterTest();
 397  
 398          $component = 'editor_atto';
 399  
 400          // Create editor drafts in:
 401          // - the system; and
 402          // - a course; and
 403          // - current user context; and
 404          // - another user.
 405  
 406          $systemcontext = \context_system::instance();
 407          // Create a course.
 408          $course = $this->getDataGenerator()->create_course();
 409          $coursecontext = \context_course::instance($course->id);
 410  
 411          // Create a user.
 412          $user = $this->getDataGenerator()->create_user();
 413          $usercontext = \context_user::instance($user->id);
 414          $this->setUser($user);
 415  
 416          // Add a fake inline image to the original post.
 417          $this->create_editor_draft($usercontext, $user->id,
 418              'id_user_intro', 'text for test user at own context');
 419          $this->create_editor_draft($usercontext, $user->id,
 420              'id_user_description', 'text for test user at own context');
 421          $this->create_editor_draft($systemcontext, $user->id,
 422              'id_system_intro', 'text for test user at system context', 2);
 423          $this->create_editor_draft($systemcontext, $user->id,
 424              'id_system_description', 'text for test user at system context', 4);
 425          $this->create_editor_draft($coursecontext, $user->id,
 426              'id_course_intro', 'text for test user at course context');
 427          $this->create_editor_draft($coursecontext, $user->id,
 428              'id_course_description', 'text for test user at course context');
 429  
 430          // Create some data as the other user too.
 431          $otheruser = $this->getDataGenerator()->create_user();
 432          $otherusercontext = \context_user::instance($otheruser->id);
 433          $this->setUser($otheruser);
 434  
 435          $this->create_editor_draft($otherusercontext, $otheruser->id,
 436              'id_user_intro', 'text for other user at own context');
 437          $this->create_editor_draft($otherusercontext, $otheruser->id,
 438              'id_user_description', 'text for other user at own context');
 439          $this->create_editor_draft($systemcontext, $otheruser->id,
 440              'id_system_intro', 'text for other user at system context');
 441          $this->create_editor_draft($systemcontext, $otheruser->id,
 442              'id_system_description', 'text for other user at system context');
 443          $this->create_editor_draft($coursecontext, $otheruser->id,
 444              'id_course_intro', 'text for other user at course context');
 445          $this->create_editor_draft($coursecontext, $otheruser->id,
 446              'id_course_description', 'text for other user at course context');
 447  
 448          // The list of users for usercontext should return user.
 449          $userlist1 = new \core_privacy\local\request\userlist($usercontext, $component);
 450          provider::get_users_in_context($userlist1);
 451          $this->assertCount(1, $userlist1);
 452          $this->assertTrue(in_array($user->id, $userlist1->get_userids()));
 453  
 454          // The list of users for otherusercontext should return otheruser.
 455          $userlist2 = new \core_privacy\local\request\userlist($otherusercontext, $component);
 456          provider::get_users_in_context($userlist2);
 457          $this->assertCount(1, $userlist2);
 458          $this->assertTrue(in_array($otheruser->id, $userlist2->get_userids()));
 459  
 460          // Add userlist1 to the approved user list.
 461          $approvedlist = new approved_userlist($usercontext, $component, $userlist1->get_userids());
 462          // Delete user data using delete_data_for_user for usercontext.
 463          provider::delete_data_for_users($approvedlist);
 464  
 465          // Re-fetch users in usercontext - The user list should now be empty.
 466          $userlist1 = new \core_privacy\local\request\userlist($usercontext, $component);
 467          provider::get_users_in_context($userlist1);
 468          $this->assertCount(0, $userlist1);
 469          // Re-fetch users in otherusercontext - The user list should not be empty (otheruser).
 470          $userlist2 = new \core_privacy\local\request\userlist($otherusercontext, $component);
 471          provider::get_users_in_context($userlist2);
 472          $this->assertCount(1, $userlist2);
 473          $this->assertTrue(in_array($otheruser->id, $userlist2->get_userids()));
 474  
 475          // The list of users for systemcontext should return user and otheruser.
 476          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
 477          provider::get_users_in_context($userlist3);
 478          $this->assertCount(2, $userlist3);
 479          $this->assertTrue(in_array($user->id, $userlist3->get_userids()));
 480          $this->assertTrue(in_array($otheruser->id, $userlist3->get_userids()));
 481  
 482          // Add $userlist3 to the approved user list in the system context.
 483          $approvedlist = new approved_userlist($systemcontext, $component, $userlist3->get_userids());
 484          // Delete user and otheruser data using delete_data_for_user.
 485          provider::delete_data_for_users($approvedlist);
 486  
 487          // Re-fetch users in systemcontext - The user list should be empty.
 488          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
 489          provider::get_users_in_context($userlist3);
 490          $this->assertCount(0, $userlist3);
 491  
 492          // The list of users for coursecontext should return user and otheruser.
 493          $userlist4 = new \core_privacy\local\request\userlist($coursecontext, $component);
 494          provider::get_users_in_context($userlist4);
 495          $this->assertCount(2, $userlist4);
 496          $this->assertTrue(in_array($user->id, $userlist4->get_userids()));
 497          $this->assertTrue(in_array($otheruser->id, $userlist4->get_userids()));
 498  
 499          // Add user to the approved user list in the course context.
 500          $approvedlist = new approved_userlist($coursecontext, $component, [$user->id]);
 501          // Delete user data using delete_data_for_user.
 502          provider::delete_data_for_users($approvedlist);
 503  
 504          // Re-fetch users in coursecontext - The user list should return otheruser.
 505          $userlist4 = new \core_privacy\local\request\userlist($coursecontext, $component);
 506          provider::get_users_in_context($userlist4);
 507          $this->assertCount(1, $userlist4);
 508          $this->assertTrue(in_array($otheruser->id, $userlist4->get_userids()));
 509      }
 510  
 511      /**
 512       * Test fetch and delete when another user has editted a draft in your
 513       * user context. Edge case.
 514       */
 515      public function test_another_user_edits_you() {
 516          global $USER, $DB;
 517          $this->resetAfterTest();
 518  
 519          $user = $this->getDataGenerator()->create_user();
 520          $usercontext = \context_user::instance($user->id);
 521          $otheruser = $this->getDataGenerator()->create_user();
 522          $otherusercontext = \context_user::instance($otheruser->id);
 523          $this->setUser($user);
 524  
 525          $userdraftintro = $this->create_editor_draft($usercontext, $otheruser->id,
 526                  'id_user_intro', 'text for test user at other context');
 527  
 528          // Test as the owning user.
 529          $this->setUser($user);
 530          $contextlist = provider::get_contexts_for_userid($user->id);
 531          $contexts = $contextlist->get_contexts();
 532          $this->assertCount(1, $contexts);
 533          $firstcontext = reset($contexts);
 534          $this->assertEquals($usercontext, $firstcontext);
 535  
 536          // Should have the data.
 537          $this->export_context_data_for_user($user->id, $usercontext, 'editor_atto');
 538          $writer = \core_privacy\local\request\writer::with_context($usercontext);
 539          $this->assertTrue($writer->has_any_data());
 540  
 541          $subcontext = [
 542              get_string('autosaves', 'editor_atto'),
 543              $userdraftintro->id,
 544          ];
 545          $data = $writer->get_data($subcontext);
 546          $this->assertEquals(\core_privacy\local\request\transform::user($otheruser->id), $data->author);
 547  
 548          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 549              \core_user::get_user($user->id),
 550              'editor_atto',
 551              [$usercontext->id]
 552          );
 553  
 554  
 555          // Deleting for this context should _not_ delete as the user does not own this draft (crazy edge case, remember).
 556          provider::delete_data_for_user($contextlist);
 557          $records = $DB->get_records('editor_atto_autosave');
 558          $this->assertNotEmpty($records);
 559          $this->assertCount(1, $records);
 560          $firstrecord = reset($records);
 561          $this->assertEquals($userdraftintro->id, $firstrecord->id);
 562      }
 563  
 564      /**
 565       * Test fetch and delete when you have edited another user's context.
 566       */
 567      public function test_another_you_edit_different_user() {
 568          global $USER, $DB;
 569          $this->resetAfterTest();
 570  
 571          $user = $this->getDataGenerator()->create_user();
 572          $usercontext = \context_user::instance($user->id);
 573          $otheruser = $this->getDataGenerator()->create_user();
 574          $otherusercontext = \context_user::instance($otheruser->id);
 575          $this->setUser($user);
 576  
 577          $userdraftintro = $this->create_editor_draft($otherusercontext, $user->id,
 578                  'id_user_intro', 'text for other user you just edited.');
 579  
 580          // Test as the context owner.
 581          $this->setUser($user);
 582          $contextlist = provider::get_contexts_for_userid($user->id);
 583          $contexts = $contextlist->get_contexts();
 584          $this->assertCount(1, $contexts);
 585          $firstcontext = reset($contexts);
 586          $this->assertEquals($otherusercontext, $firstcontext);
 587  
 588          // Should have the data.
 589          $this->export_context_data_for_user($user->id, $otherusercontext, 'editor_atto');
 590          $writer = \core_privacy\local\request\writer::with_context($otherusercontext);
 591          $this->assertTrue($writer->has_any_data());
 592  
 593          $subcontext = [
 594              get_string('autosaves', 'editor_atto'),
 595              $userdraftintro->id,
 596          ];
 597          $data = $writer->get_data($subcontext);
 598          $this->assertFalse(isset($data->author));
 599  
 600          $contextlist = new \core_privacy\tests\request\approved_contextlist(
 601              \core_user::get_user($user->id),
 602              'editor_atto',
 603              [$otherusercontext->id]
 604          );
 605          provider::delete_data_for_user($contextlist);
 606          $this->assertEmpty($DB->get_records('editor_atto_autosave'));
 607      }
 608  
 609     /**
 610       * Create an editor draft.
 611       *
 612       * @param   \context    $context The context to create the draft for.
 613       * @param   int         $userid The ID to create the draft for.
 614       * @param   string      $elementid The elementid for the editor.
 615       * @param   string      $text The text to write.
 616       * @param   int         $filecount The number of files to create.
 617       * @return  \stdClass   The editor draft.
 618       */
 619      protected function create_editor_draft(\context $context, $userid, $elementid, $text, $filecount = 0) {
 620          global $DB;
 621  
 622          $draftid = file_get_unused_draft_itemid();
 623          $fs = get_file_storage();
 624  
 625          for ($i = 0; $i < $filecount; $i++) {
 626              $fs->create_file_from_string([
 627                      'contextid' => $context->id,
 628                      'component' => 'user',
 629                      'filearea'  => 'draft',
 630                      'itemid'    => $draftid,
 631                      'filepath'  => '/',
 632                      'filename'  => "example_{$i}.txt",
 633                  ],
 634              "Awesome example of a text file with id {$i} for {$context->id} and {$elementid}");
 635          }
 636  
 637          $id = $DB->insert_record('editor_atto_autosave', (object) [
 638                  'elementid' => $elementid,
 639                  'contextid' => $context->id,
 640                  'userid' => $userid,
 641                  'drafttext' => $text,
 642                  'draftid' => $draftid,
 643                  'pageinstance' => 'example_page_instance_' . rand(1, 1000),
 644                  'timemodified' => time(),
 645  
 646                  // Page hash doesn't matter for our purposes.
 647                  'pagehash' => sha1("{$userid}/{$context->id}/{$elementid}/{$draftid}"),
 648              ]);
 649  
 650          return $DB->get_record('editor_atto_autosave', ['id' => $id]);
 651      }
 652  }