MDL-63701 editor_atto: Add support for removal of context users
[moodle.git] / lib / editor / atto / tests / privacy_provider.php
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/>.
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  */
26 defined('MOODLE_INTERNAL') || die();
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;
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();
47         // Create editor drafts in:
48         // - the system; and
49         // - a course; and
50         // - current user context; and
51         // - another user.
53         $systemcontext = \context_system::instance();
54         $course = $this->getDataGenerator()->create_course();
55         $coursecontext = \context_course::instance($course->id);
57         $usercontextids = [];
58         $user = $this->getDataGenerator()->create_user();
59         $this->setUser($user);
61         $usercontext = \context_user::instance($user->id);
62         $usercontextids[] = $usercontext->id;
63         $usercontextids[] = $systemcontext->id;
64         $usercontextids[] = $coursecontext->id;
66         // Add a fake inline image to the original post.
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');
81         // Create some data as the other user too.
82         $otherusercontextids = [];
83         $otheruser = $this->getDataGenerator()->create_user();
84         $this->setUser($otheruser);
86         $otherusercontext = \context_user::instance($otheruser->id);
87         $otherusercontextids[] = $otherusercontext->id;
88         $otherusercontextids[] = $systemcontext->id;
89         $otherusercontextids[] = $coursecontext->id;
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');
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);
109         // There are three contexts in the list.
110         $this->assertCount(3, $contextlist);
112         // Check the list against the expected list of contexts.
113         foreach ($contextlist as $context) {
114             $this->assertContains($context->id, $usercontextids);
115         }
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());
123         $subcontextbase = [get_string('autosaves', 'editor_atto')];
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])));
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     }
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();
149         // Create editor drafts in:
150         // - the system; and
151         // - a course; and
152         // - current user context; and
153         // - another user.
155         $systemcontext = \context_system::instance();
156         $course = $this->getDataGenerator()->create_course();
157         $coursecontext = \context_course::instance($course->id);
159         $usercontextids = [];
160         $user = $this->getDataGenerator()->create_user();
161         $this->setUser($user);
163         $usercontext = \context_user::instance($user->id);
164         $usercontextids[] = $usercontext->id;
165         $usercontextids[] = $systemcontext->id;
166         $usercontextids[] = $coursecontext->id;
168         // Add a fake inline image to the original post.
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');
183         // Create some data as the other user too.
184         $otherusercontextids = [];
185         $otheruser = $this->getDataGenerator()->create_user();
186         $this->setUser($otheruser);
188         $otherusercontext = \context_user::instance($otheruser->id);
189         $otherusercontextids[] = $otherusercontext->id;
190         $otherusercontextids[] = $systemcontext->id;
191         $otherusercontextids[] = $coursecontext->id;
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');
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]));
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]));
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]));
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     }
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();
235         // Create editor drafts in:
236         // - the system; and
237         // - a course; and
238         // - current user context; and
239         // - another user.
241         $systemcontext = \context_system::instance();
242         $course = $this->getDataGenerator()->create_course();
243         $coursecontext = \context_course::instance($course->id);
245         $usercontextids = [];
246         $user = $this->getDataGenerator()->create_user();
247         $this->setUser($user);
249         $usercontext = \context_user::instance($user->id);
250         $usercontextids[] = $usercontext->id;
251         $usercontextids[] = $systemcontext->id;
252         $usercontextids[] = $coursecontext->id;
254         // Add a fake inline image to the original post.
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');
269         // Create some data as the other user too.
270         $otherusercontextids = [];
271         $otheruser = $this->getDataGenerator()->create_user();
272         $this->setUser($otheruser);
274         $otherusercontext = \context_user::instance($otheruser->id);
275         $otherusercontextids[] = $otherusercontext->id;
276         $otherusercontextids[] = $systemcontext->id;
277         $otherusercontextids[] = $coursecontext->id;
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');
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]));
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]));
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]));
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         ]));
324         $this->assertCount(2, $DB->get_records('editor_atto_autosave', [
325             'contextid' => $systemcontext->id,
326             'userid' => $otheruser->id,
327         ]));
328     }
330     /**
331      * Test that user data with different contexts is fetched.
332      */
333     public function test_get_users_in_context() {
334         $this->resetAfterTest();
336         $component = 'editor_atto';
338         // Create editor drafts in:
339         // - the system; and
340         // - a course; and
341         // - current user context; and
342         // - another user.
344         $systemcontext = \context_system::instance();
345         // Create a course.
346         $course = $this->getDataGenerator()->create_course();
347         $coursecontext = \context_course::instance($course->id);
349         // Create a user.
350         $user = $this->getDataGenerator()->create_user();
351         $usercontext = \context_user::instance($user->id);
352         $this->setUser($user);
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');
364         // Create user2.
365         $user2 = $this->getDataGenerator()->create_user();
366         $this->setUser($user2);
368         $this->create_editor_draft($coursecontext, $user2->id,
369             'id_course_description', 'text for test user2 at course context');
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()));
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()));
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     }
391     /**
392      * Test that data for users in approved userlist is deleted.
393      */
394     public function test_delete_data_for_users() {
395         $this->resetAfterTest();
397         $component = 'editor_atto';
399         // Create editor drafts in:
400         // - the system; and
401         // - a course; and
402         // - current user context; and
403         // - another user.
405         $systemcontext = \context_system::instance();
406         // Create a course.
407         $course = $this->getDataGenerator()->create_course();
408         $coursecontext = \context_course::instance($course->id);
410         // Create a user.
411         $user = $this->getDataGenerator()->create_user();
412         $usercontext = \context_user::instance($user->id);
413         $this->setUser($user);
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');
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);
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');
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()));
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()));
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);
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()));
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()));
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);
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);
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()));
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);
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     }
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();
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);
524         $userdraftintro = $this->create_editor_draft($usercontext, $otheruser->id,
525                 'id_user_intro', 'text for test user at other context');
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);
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());
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);
547         $contextlist = new \core_privacy\tests\request\approved_contextlist(
548             \core_user::get_user($user->id),
549             'editor_atto',
550             [$usercontext->id]
551         );
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     }
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();
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);
576         $userdraftintro = $this->create_editor_draft($otherusercontext, $user->id,
577                 'id_user_intro', 'text for other user you just edited.');
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);
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());
592         $subcontext = [
593             get_string('autosaves', 'editor_atto'),
594             $userdraftintro->id,
595         ];
596         $data = $writer->get_data($subcontext);
597         $this->assertFalse(isset($data->author));
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     }
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;
621         $draftid = file_get_unused_draft_itemid();
622         $fs = get_file_storage();
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         }
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(),
645                 // Page hash doesn't matter for our purposes.
646                 'pagehash' => sha1("{$userid}/{$context->id}/{$elementid}/{$draftid}"),
647             ]);
649         return $DB->get_record('editor_atto_autosave', ['id' => $id]);
650     }