Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Base class for unit tests for mod_assign.
19
 *
20
 * @package    mod_assign
21
 * @copyright  2018 Adrian Greeve <adrian@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace mod_assign\privacy;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
global $CFG;
30
require_once($CFG->dirroot . '/mod/assign/locallib.php');
31
 
32
use core_privacy\tests\provider_testcase;
33
use core_privacy\local\request\writer;
34
use core_privacy\local\request\approved_contextlist;
35
use mod_assign\privacy\provider;
36
 
37
/**
38
 * Unit tests for mod/assign/classes/privacy/
39
 *
40
 * @copyright  2018 Adrian Greeve <adrian@moodle.com>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class provider_test extends provider_testcase {
44
 
45
    /**
46
     * Convenience method for creating a submission.
47
     *
48
     * @param  assign  $assign The assign object
49
     * @param  stdClass  $user The user object
50
     * @param  string  $submissiontext Submission text
51
     * @param  integer $attemptnumber The attempt number
52
     * @return object A submission object.
53
     */
54
    protected function create_submission($assign, $user, $submissiontext, $attemptnumber = 0) {
55
        $submission = $assign->get_user_submission($user->id, true, $attemptnumber);
56
        $submission->onlinetext_editor = ['text' => $submissiontext,
57
                                         'format' => FORMAT_MOODLE];
58
 
59
        $this->setUser($user);
60
        $notices = [];
61
        $assign->save_submission($submission, $notices);
62
        return $submission;
63
    }
64
 
65
    /**
66
     * Convenience function to create an instance of an assignment.
67
     *
68
     * @param array $params Array of parameters to pass to the generator
69
     * @return assign The assign class.
70
     */
71
    protected function create_instance($params = array()) {
72
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
73
        $instance = $generator->create_instance($params);
74
        $cm = get_coursemodule_from_instance('assign', $instance->id);
75
        $context = \context_module::instance($cm->id);
76
        return new \assign($context, $cm, $params['course']);
77
    }
78
 
79
    /**
80
     * Test that getting the contexts for a user works.
81
     */
11 efrain 82
    public function test_get_contexts_for_userid(): void {
1 efrain 83
        global $DB;
84
        $this->resetAfterTest();
85
 
86
        $course1 = $this->getDataGenerator()->create_course();
87
        $course2 = $this->getDataGenerator()->create_course();
88
        $course3 = $this->getDataGenerator()->create_course();
89
 
90
        $user1 = $this->getDataGenerator()->create_user();
91
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
92
        $this->getDataGenerator()->enrol_user($user1->id, $course3->id, 'student');
93
        // Need a second user to create content in other assignments.
94
        $user2 = $this->getDataGenerator()->create_user();
95
        $this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
96
 
97
        // Create multiple assignments.
98
        // Assignment with a text submission.
99
        $assign1 = $this->create_instance(['course' => $course1]);
100
        // Assignment two in a different course that the user is not enrolled in.
101
        $assign2 = $this->create_instance(['course' => $course2]);
102
        // Assignment three has an entry in the override table.
103
        $assign3 = $this->create_instance(['course' => $course3, 'cutoffdate' => time()]);
104
        // Assignment four - blind marking.
105
        $assign4 = $this->create_instance(['course' => $course1, 'blindmarking' => 1]);
106
        // Assignment five - user flags.
107
        $assign5 = $this->create_instance(['course' => $course3]);
108
 
109
        // Override has to be manually inserted into the DB.
110
        $overridedata = new \stdClass();
111
        $overridedata->assignid = $assign3->get_instance()->id;
112
        $overridedata->userid = $user1->id;
113
        $overridedata->duedate = time();
114
        $DB->insert_record('assign_overrides', $overridedata);
115
        // Assign unique id for blind marking in assignment four for user 1.
116
        \assign::get_uniqueid_for_user_static($assign4->get_instance()->id, $user1->id);
117
        // Create an entry in the user flags table.
118
        $assign5->get_user_flags($user1->id, true);
119
 
120
        // The user will be in these contexts.
121
        $usercontextids = [
122
            $assign1->get_context()->id,
123
            $assign3->get_context()->id,
124
            $assign4->get_context()->id,
125
            $assign5->get_context()->id,
126
        ];
127
 
128
        $submission = new \stdClass();
129
        $submission->assignment = $assign1->get_instance()->id;
130
        $submission->userid = $user1->id;
131
        $submission->timecreated = time();
132
        $submission->onlinetext_editor = ['text' => 'Submission text',
133
                                         'format' => FORMAT_MOODLE];
134
 
135
        $this->setUser($user1);
136
        $notices = [];
137
        $assign1->save_submission($submission, $notices);
138
 
139
        // Create a submission for the second assignment.
140
        $submission->assignment = $assign2->get_instance()->id;
141
        $submission->userid = $user2->id;
142
        $this->setUser($user2);
143
        $assign2->save_submission($submission, $notices);
144
 
145
        $contextlist = provider::get_contexts_for_userid($user1->id);
146
        $this->assertEquals(count($usercontextids), count($contextlist->get_contextids()));
147
        // There should be no difference between the contexts.
148
        $this->assertEmpty(array_diff($usercontextids, $contextlist->get_contextids()));
149
    }
150
 
151
    /**
152
     * Test returning a list of user IDs related to a context (assign).
153
     */
11 efrain 154
    public function test_get_users_in_context(): void {
1 efrain 155
        global $DB;
156
 
157
        $this->resetAfterTest();
158
 
159
        $course = $this->getDataGenerator()->create_course();
160
 
161
        // Only made a comment on a submission.
162
        $user1 = $this->getDataGenerator()->create_user();
163
        // User 2 only has information about an activity override.
164
        $user2 = $this->getDataGenerator()->create_user();
165
        // User 3 made a submission.
166
        $user3 = $this->getDataGenerator()->create_user();
167
        // User 4 makes a submission and it is marked by the teacher.
168
        $user4 = $this->getDataGenerator()->create_user();
169
        // Grading and providing feedback as a teacher.
170
        $user5 = $this->getDataGenerator()->create_user();
171
        // This user has no entries and should not show up.
172
        $user6 = $this->getDataGenerator()->create_user();
173
 
174
        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
175
        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
176
        $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
177
        $this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
178
        $this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
179
        $this->getDataGenerator()->enrol_user($user6->id, $course->id, 'student');
180
 
181
        $assign1 = $this->create_instance(['course' => $course,
182
                'assignsubmission_onlinetext_enabled' => true,
183
                'assignfeedback_comments_enabled' => true]);
184
        $assign2 = $this->create_instance(['course' => $course]);
185
 
186
        $context = $assign1->get_context();
187
 
188
        // Jam an entry in the comments table for user 1.
189
        $comment = (object) [
190
            'contextid' => $context->id,
191
            'component' => 'assignsubmission_comments',
192
            'commentarea' => 'submission_comments',
193
            'itemid' => 5,
194
            'content' => 'A comment by user 1',
195
            'format' => 0,
196
            'userid' => $user1->id,
197
            'timecreated' => time()
198
        ];
199
        $DB->insert_record('comments', $comment);
200
 
201
        $this->setUser($user5); // Set the user to the teacher.
202
 
203
        $overridedata = new \stdClass();
204
        $overridedata->assignid = $assign1->get_instance()->id;
205
        $overridedata->userid = $user2->id;
206
        $overridedata->duedate = time();
207
        $overridedata->allowsubmissionsfromdate = time();
208
        $overridedata->cutoffdate = time();
209
        $DB->insert_record('assign_overrides', $overridedata);
210
 
211
        $submissiontext = 'My first submission';
212
        $submission = $this->create_submission($assign1, $user3, $submissiontext);
213
 
214
        $submissiontext = 'My first submission';
215
        $submission = $this->create_submission($assign1, $user4, $submissiontext);
216
 
217
        $this->setUser($user5);
218
 
219
        $grade = '72.00';
220
        $teachercommenttext = 'This is better. Thanks.';
221
        $data = new \stdClass();
222
        $data->attemptnumber = 1;
223
        $data->grade = $grade;
224
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
225
 
226
        // Give the submission a grade.
227
        $assign1->save_grade($user4->id, $data);
228
 
229
        $userlist = new \core_privacy\local\request\userlist($context, 'assign');
230
        provider::get_users_in_context($userlist);
231
        $userids = $userlist->get_userids();
232
        $this->assertTrue(in_array($user1->id, $userids));
233
        $this->assertTrue(in_array($user2->id, $userids));
234
        $this->assertTrue(in_array($user3->id, $userids));
235
        $this->assertTrue(in_array($user4->id, $userids));
236
        $this->assertTrue(in_array($user5->id, $userids));
237
        $this->assertFalse(in_array($user6->id, $userids));
238
    }
239
 
240
    /**
241
     * Test that a student with multiple submissions and grades is returned with the correct data.
242
     */
11 efrain 243
    public function test_export_user_data_student(): void {
1 efrain 244
        global $DB;
245
        $this->resetAfterTest();
246
        $course = $this->getDataGenerator()->create_course();
247
        $coursecontext = \context_course::instance($course->id);
248
 
249
        $user = $this->getDataGenerator()->create_user();
250
        $teacher = $this->getDataGenerator()->create_user();
251
        $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
252
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
253
        $assign = $this->create_instance([
254
                'course' => $course,
255
                'name' => 'Assign 1',
256
                'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
257
                'maxattempts' => 3,
258
                'assignsubmission_onlinetext_enabled' => true,
259
                'assignfeedback_comments_enabled' => true
260
            ]);
261
 
262
        $context = $assign->get_context();
263
        // Create some submissions (multiple attempts) for a student.
264
        $submissiontext = 'My first submission';
265
        $submission = $this->create_submission($assign, $user, $submissiontext);
266
 
267
        $this->setUser($teacher);
268
 
269
        $overridedata = new \stdClass();
270
        $overridedata->assignid = $assign->get_instance()->id;
271
        $overridedata->userid = $user->id;
272
        $overridedata->duedate = time();
273
        $overridedata->allowsubmissionsfromdate = time();
274
        $overridedata->cutoffdate = time();
275
        $DB->insert_record('assign_overrides', $overridedata);
276
 
277
        $grade1 = '67.00';
278
        $teachercommenttext = 'Please try again.';
279
        $data = new \stdClass();
280
        $data->attemptnumber = 0;
281
        $data->grade = $grade1;
282
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
283
 
284
        // Give the submission a grade.
285
        $assign->save_grade($user->id, $data);
286
 
287
        $submissiontext2 = 'My second submission';
288
        $submission = $this->create_submission($assign, $user, $submissiontext2, 1);
289
 
290
        $this->setUser($teacher);
291
 
292
        $grade2 = '72.00';
293
        $teachercommenttext2 = 'This is better. Thanks.';
294
        $data = new \stdClass();
295
        $data->attemptnumber = 1;
296
        $data->grade = $grade2;
297
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext2, 'format' => FORMAT_MOODLE];
298
 
299
        // Give the submission a grade.
300
        $assign->save_grade($user->id, $data);
301
 
302
        /** @var \core_privacy\tests\request\content_writer $writer */
303
        $writer = writer::with_context($context);
304
        $this->assertFalse($writer->has_any_data());
305
 
306
        // The student should have some text submitted.
307
        // Add the course context as well to make sure there is no error.
308
        $approvedlist = new approved_contextlist($user, 'mod_assign', [$context->id, $coursecontext->id]);
309
        provider::export_user_data($approvedlist);
310
 
311
        // Check that we have general details about the assignment.
312
        $this->assertEquals('Assign 1', $writer->get_data()->name);
313
        // Check Submissions.
314
        $this->assertEquals($submissiontext, $writer->get_data(['attempt 1', 'Submission Text'])->text);
315
        $this->assertEquals($submissiontext2, $writer->get_data(['attempt 2', 'Submission Text'])->text);
316
        $this->assertEquals(1, $writer->get_data(['attempt 1', 'submission'])->attemptnumber);
317
        $this->assertEquals(2, $writer->get_data(['attempt 2', 'submission'])->attemptnumber);
318
        // Check grades.
319
        $this->assertEquals((float)$grade1, $writer->get_data(['attempt 1', 'grade'])->grade);
320
        $this->assertEquals((float)$grade2, $writer->get_data(['attempt 2', 'grade'])->grade);
321
        // Check feedback.
322
        $this->assertStringContainsString($teachercommenttext, $writer->get_data(['attempt 1', 'Feedback comments'])->commenttext);
323
        $this->assertStringContainsString($teachercommenttext2, $writer->get_data(['attempt 2', 'Feedback comments'])->commenttext);
324
 
325
        // Check override data was exported correctly.
326
        $overrideexport = $writer->get_data(['Overrides']);
327
        $this->assertEquals(\core_privacy\local\request\transform::datetime($overridedata->duedate),
328
                $overrideexport->duedate);
329
        $this->assertEquals(\core_privacy\local\request\transform::datetime($overridedata->cutoffdate),
330
                $overrideexport->cutoffdate);
331
        $this->assertEquals(\core_privacy\local\request\transform::datetime($overridedata->allowsubmissionsfromdate),
332
                $overrideexport->allowsubmissionsfromdate);
333
    }
334
 
335
    /**
336
     * Tests the data returned for a teacher.
337
     */
11 efrain 338
    public function test_export_user_data_teacher(): void {
1 efrain 339
        $this->resetAfterTest();
340
        $course = $this->getDataGenerator()->create_course();
341
        $coursecontext = \context_course::instance($course->id);
342
 
343
        $user1 = $this->getDataGenerator()->create_user();
344
        $user2 = $this->getDataGenerator()->create_user();
345
        $teacher = $this->getDataGenerator()->create_user();
346
        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
347
        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
348
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
349
        $assign = $this->create_instance([
350
                'course' => $course,
351
                'name' => 'Assign 1',
352
                'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
353
                'maxattempts' => 3,
354
                'assignsubmission_onlinetext_enabled' => true,
355
                'assignfeedback_comments_enabled' => true
356
            ]);
357
 
358
        $context = $assign->get_context();
359
 
360
        // Create and grade some submissions from the students.
361
        $submissiontext = 'My first submission';
362
        $submission = $this->create_submission($assign, $user1, $submissiontext);
363
 
364
        $this->setUser($teacher);
365
 
366
        $grade1 = '54.00';
367
        $teachercommenttext = 'Comment on user 1 attempt 1.';
368
        $data = new \stdClass();
369
        $data->attemptnumber = 0;
370
        $data->grade = $grade1;
371
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
372
 
373
        // Give the submission a grade.
374
        $assign->save_grade($user1->id, $data);
375
 
376
        // Create and grade some submissions from the students.
377
        $submissiontext2 = 'My first submission for user 2';
378
        $submission = $this->create_submission($assign, $user2, $submissiontext2);
379
 
380
        $this->setUser($teacher);
381
 
382
        $grade2 = '56.00';
383
        $teachercommenttext2 = 'Comment on user 2 first attempt.';
384
        $data = new \stdClass();
385
        $data->attemptnumber = 0;
386
        $data->grade = $grade2;
387
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext2, 'format' => FORMAT_MOODLE];
388
 
389
        // Give the submission a grade.
390
        $assign->save_grade($user2->id, $data);
391
 
392
        // Create and grade some submissions from the students.
393
        $submissiontext3 = 'My second submission for user 2';
394
        $submission = $this->create_submission($assign, $user2, $submissiontext3, 1);
395
 
396
        $this->setUser($teacher);
397
 
398
        $grade3 = '83.00';
399
        $teachercommenttext3 = 'Comment on user 2 another attempt.';
400
        $data = new \stdClass();
401
        $data->attemptnumber = 1;
402
        $data->grade = $grade3;
403
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext3, 'format' => FORMAT_MOODLE];
404
 
405
        // Give the submission a grade.
406
        $assign->save_grade($user2->id, $data);
407
 
408
        // Set up some flags.
409
        $duedate = time();
410
        $flagdata = $assign->get_user_flags($teacher->id, true);
411
        $flagdata->mailed = 1;
412
        $flagdata->extensionduedate = $duedate;
413
        $assign->update_user_flags($flagdata);
414
 
415
        /** @var \core_privacy\tests\request\content_writer $writer */
416
        $writer = writer::with_context($context);
417
        $this->assertFalse($writer->has_any_data());
418
 
419
        // The student should have some text submitted.
420
        $approvedlist = new approved_contextlist($teacher, 'mod_assign', [$context->id, $coursecontext->id]);
421
        provider::export_user_data($approvedlist);
422
 
423
        // Check flag metadata.
424
        $metadata = $writer->get_all_metadata();
425
        $this->assertEquals(\core_privacy\local\request\transform::yesno(1), $metadata['mailed']->value);
426
        $this->assertEquals(\core_privacy\local\request\transform::datetime($duedate), $metadata['extensionduedate']->value);
427
 
428
        // Check for student grades given.
429
        $student1grade = $writer->get_data(['studentsubmissions', $user1->id, 'attempt 1', 'grade']);
430
        $this->assertEquals((float)$grade1, $student1grade->grade);
431
        $student2grade1 = $writer->get_data(['studentsubmissions', $user2->id, 'attempt 1', 'grade']);
432
        $this->assertEquals((float)$grade2, $student2grade1->grade);
433
        $student2grade2 = $writer->get_data(['studentsubmissions', $user2->id, 'attempt 2', 'grade']);
434
        $this->assertEquals((float)$grade3, $student2grade2->grade);
435
        // Check for feedback given to students.
436
        $this->assertStringContainsString($teachercommenttext, $writer->get_data(['studentsubmissions', $user1->id, 'attempt 1',
437
                'Feedback comments'])->commenttext);
438
        $this->assertStringContainsString($teachercommenttext2, $writer->get_data(['studentsubmissions', $user2->id, 'attempt 1',
439
                'Feedback comments'])->commenttext);
440
        $this->assertStringContainsString($teachercommenttext3, $writer->get_data(['studentsubmissions', $user2->id, 'attempt 2',
441
                'Feedback comments'])->commenttext);
442
    }
443
 
444
    /**
445
     * A test for deleting all user data for a given context.
446
     */
11 efrain 447
    public function test_delete_data_for_all_users_in_context(): void {
1 efrain 448
        global $DB;
449
        $this->resetAfterTest();
450
        $course = $this->getDataGenerator()->create_course();
451
 
452
        $user1 = $this->getDataGenerator()->create_user();
453
        $user2 = $this->getDataGenerator()->create_user();
454
        $teacher = $this->getDataGenerator()->create_user();
455
        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
456
        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
457
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
458
        $assign = $this->create_instance([
459
                'course' => $course,
460
                'name' => 'Assign 1',
461
                'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
462
                'maxattempts' => 3,
463
                'assignsubmission_onlinetext_enabled' => true,
464
                'assignfeedback_comments_enabled' => true
465
            ]);
466
 
467
        $context = $assign->get_context();
468
 
469
        // Create and grade some submissions from the students.
470
        $submissiontext = 'My first submission';
471
        $submission = $this->create_submission($assign, $user1, $submissiontext);
472
 
473
        $this->setUser($teacher);
474
 
475
        // Overrides for both students.
476
        $overridedata = new \stdClass();
477
        $overridedata->assignid = $assign->get_instance()->id;
478
        $overridedata->userid = $user1->id;
479
        $overridedata->duedate = time();
480
        $DB->insert_record('assign_overrides', $overridedata);
481
        $overridedata->userid = $user2->id;
482
        $DB->insert_record('assign_overrides', $overridedata);
483
        assign_update_events($assign);
484
 
485
        $grade1 = '54.00';
486
        $teachercommenttext = 'Comment on user 1 attempt 1.';
487
        $data = new \stdClass();
488
        $data->attemptnumber = 0;
489
        $data->grade = $grade1;
490
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
491
 
492
        // Give the submission a grade.
493
        $assign->save_grade($user1->id, $data);
494
 
495
        // Create and grade some submissions from the students.
496
        $submissiontext2 = 'My first submission for user 2';
497
        $submission = $this->create_submission($assign, $user2, $submissiontext2);
498
 
499
        $this->setUser($teacher);
500
 
501
        $grade2 = '56.00';
502
        $teachercommenttext2 = 'Comment on user 2 first attempt.';
503
        $data = new \stdClass();
504
        $data->attemptnumber = 0;
505
        $data->grade = $grade2;
506
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext2, 'format' => FORMAT_MOODLE];
507
 
508
        // Give the submission a grade.
509
        $assign->save_grade($user2->id, $data);
510
 
511
        // Create and grade some submissions from the students.
512
        $submissiontext3 = 'My second submission for user 2';
513
        $submission = $this->create_submission($assign, $user2, $submissiontext3, 1);
514
 
515
        $this->setUser($teacher);
516
 
517
        $grade3 = '83.00';
518
        $teachercommenttext3 = 'Comment on user 2 another attempt.';
519
        $data = new \stdClass();
520
        $data->attemptnumber = 1;
521
        $data->grade = $grade3;
522
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext3, 'format' => FORMAT_MOODLE];
523
 
524
        // Give the submission a grade.
525
        $assign->save_grade($user2->id, $data);
526
 
527
        // Delete all user data for this assignment.
528
        provider::delete_data_for_all_users_in_context($context);
529
 
530
        // Check all relevant tables.
531
        $records = $DB->get_records('assign_submission');
532
        $this->assertEmpty($records);
533
        $records = $DB->get_records('assign_grades');
534
        $this->assertEmpty($records);
535
        $records = $DB->get_records('assignsubmission_onlinetext');
536
        $this->assertEmpty($records);
537
        $records = $DB->get_records('assignfeedback_comments');
538
        $this->assertEmpty($records);
539
 
540
        // Check that overrides and the calendar events are deleted.
541
        $records = $DB->get_records('event');
542
        $this->assertEmpty($records);
543
        $records = $DB->get_records('assign_overrides');
544
        $this->assertEmpty($records);
545
    }
546
 
547
    /**
548
     * A test for deleting all user data for one user.
549
     */
11 efrain 550
    public function test_delete_data_for_user(): void {
1 efrain 551
        global $DB;
552
        $this->resetAfterTest();
553
        $course = $this->getDataGenerator()->create_course();
554
 
555
        $coursecontext = \context_course::instance($course->id);
556
 
557
        $user1 = $this->getDataGenerator()->create_user();
558
        $user2 = $this->getDataGenerator()->create_user();
559
        $teacher = $this->getDataGenerator()->create_user();
560
        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
561
        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
562
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
563
        $assign = $this->create_instance([
564
                'course' => $course,
565
                'name' => 'Assign 1',
566
                'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL,
567
                'maxattempts' => 3,
568
                'assignsubmission_onlinetext_enabled' => true,
569
                'assignfeedback_comments_enabled' => true
570
            ]);
571
 
572
        $context = $assign->get_context();
573
 
574
        // Create and grade some submissions from the students.
575
        $submissiontext = 'My first submission';
576
        $submission1 = $this->create_submission($assign, $user1, $submissiontext);
577
 
578
        $this->setUser($teacher);
579
 
580
        // Overrides for both students.
581
        $overridedata = new \stdClass();
582
        $overridedata->assignid = $assign->get_instance()->id;
583
        $overridedata->userid = $user1->id;
584
        $overridedata->duedate = time();
585
        $DB->insert_record('assign_overrides', $overridedata);
586
        $overridedata->userid = $user2->id;
587
        $DB->insert_record('assign_overrides', $overridedata);
588
        assign_update_events($assign);
589
 
590
        $grade1 = '54.00';
591
        $teachercommenttext = 'Comment on user 1 attempt 1.';
592
        $data = new \stdClass();
593
        $data->attemptnumber = 0;
594
        $data->grade = $grade1;
595
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
596
 
597
        // Give the submission a grade.
598
        $assign->save_grade($user1->id, $data);
599
 
600
        // Create and grade some submissions from the students.
601
        $submissiontext2 = 'My first submission for user 2';
602
        $submission2 = $this->create_submission($assign, $user2, $submissiontext2);
603
 
604
        $this->setUser($teacher);
605
 
606
        $grade2 = '56.00';
607
        $teachercommenttext2 = 'Comment on user 2 first attempt.';
608
        $data = new \stdClass();
609
        $data->attemptnumber = 0;
610
        $data->grade = $grade2;
611
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext2, 'format' => FORMAT_MOODLE];
612
 
613
        // Give the submission a grade.
614
        $assign->save_grade($user2->id, $data);
615
 
616
        // Create and grade some submissions from the students.
617
        $submissiontext3 = 'My second submission for user 2';
618
        $submission3 = $this->create_submission($assign, $user2, $submissiontext3, 1);
619
 
620
        $this->setUser($teacher);
621
 
622
        $grade3 = '83.00';
623
        $teachercommenttext3 = 'Comment on user 2 another attempt.';
624
        $data = new \stdClass();
625
        $data->attemptnumber = 1;
626
        $data->grade = $grade3;
627
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext3, 'format' => FORMAT_MOODLE];
628
 
629
        // Give the submission a grade.
630
        $assign->save_grade($user2->id, $data);
631
 
632
        // Delete user 2's data.
633
        $approvedlist = new approved_contextlist($user2, 'mod_assign', [$context->id, $coursecontext->id]);
634
        provider::delete_data_for_user($approvedlist);
635
 
636
        // Check all relevant tables.
637
        $records = $DB->get_records('assign_submission');
638
        foreach ($records as $record) {
639
            $this->assertEquals($user1->id, $record->userid);
640
            $this->assertNotEquals($user2->id, $record->userid);
641
        }
642
        $records = $DB->get_records('assign_grades');
643
        foreach ($records as $record) {
644
            $this->assertEquals($user1->id, $record->userid);
645
            $this->assertNotEquals($user2->id, $record->userid);
646
        }
647
        $records = $DB->get_records('assignsubmission_onlinetext');
648
        $this->assertCount(1, $records);
649
        $record = array_shift($records);
650
        // The only submission is for user 1.
651
        $this->assertEquals($submission1->id, $record->submission);
652
        $records = $DB->get_records('assignfeedback_comments');
653
        $this->assertCount(1, $records);
654
        $record = array_shift($records);
655
        // The only record is the feedback comment for user 1.
656
        $this->assertEquals($teachercommenttext, $record->commenttext);
657
 
658
        // Check calendar events as well as assign overrides.
659
        $records = $DB->get_records('event');
660
        $this->assertCount(1, $records);
661
        $record = array_shift($records);
662
        // The remaining event should be for user 1.
663
        $this->assertEquals($user1->id, $record->userid);
664
        // Now for assign_overrides
665
        $records = $DB->get_records('assign_overrides');
666
        $this->assertCount(1, $records);
667
        $record = array_shift($records);
668
        // The remaining event should be for user 1.
669
        $this->assertEquals($user1->id, $record->userid);
670
    }
671
 
672
    /**
673
     * A test for deleting all user data for a bunch of users.
674
     */
11 efrain 675
    public function test_delete_data_for_users(): void {
1 efrain 676
        global $DB;
677
 
678
        $this->resetAfterTest();
679
 
680
        $course = $this->getDataGenerator()->create_course();
681
 
682
        // Only made a comment on a submission.
683
        $user1 = $this->getDataGenerator()->create_user();
684
        // User 2 only has information about an activity override.
685
        $user2 = $this->getDataGenerator()->create_user();
686
        // User 3 made a submission.
687
        $user3 = $this->getDataGenerator()->create_user();
688
        // User 4 makes a submission and it is marked by the teacher.
689
        $user4 = $this->getDataGenerator()->create_user();
690
        // Grading and providing feedback as a teacher.
691
        $user5 = $this->getDataGenerator()->create_user();
692
        // This user has entries in assignment 2 and should not have their data deleted.
693
        $user6 = $this->getDataGenerator()->create_user();
694
 
695
        $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student');
696
        $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
697
        $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student');
698
        $this->getDataGenerator()->enrol_user($user4->id, $course->id, 'student');
699
        $this->getDataGenerator()->enrol_user($user5->id, $course->id, 'editingteacher');
700
        $this->getDataGenerator()->enrol_user($user6->id, $course->id, 'student');
701
 
702
        $assign1 = $this->create_instance(['course' => $course,
703
                'assignsubmission_onlinetext_enabled' => true,
704
                'assignfeedback_comments_enabled' => true]);
705
        $assign2 = $this->create_instance(['course' => $course,
706
                'assignsubmission_onlinetext_enabled' => true,
707
                'assignfeedback_comments_enabled' => true]);
708
 
709
        $context = $assign1->get_context();
710
 
711
        // Jam an entry in the comments table for user 1.
712
        $comment = (object) [
713
            'contextid' => $context->id,
714
            'component' => 'assignsubmission_comments',
715
            'commentarea' => 'submission_comments',
716
            'itemid' => 5,
717
            'content' => 'A comment by user 1',
718
            'format' => 0,
719
            'userid' => $user1->id,
720
            'timecreated' => time()
721
        ];
722
        $DB->insert_record('comments', $comment);
723
 
724
        $this->setUser($user5); // Set the user to the teacher.
725
 
726
        $overridedata = new \stdClass();
727
        $overridedata->assignid = $assign1->get_instance()->id;
728
        $overridedata->userid = $user2->id;
729
        $overridedata->duedate = time();
730
        $overridedata->allowsubmissionsfromdate = time();
731
        $overridedata->cutoffdate = time();
732
        $DB->insert_record('assign_overrides', $overridedata);
733
 
734
        $submissiontext = 'My first submission';
735
        $submission = $this->create_submission($assign1, $user3, $submissiontext);
736
 
737
        $submissiontext = 'My first submission';
738
        $submission = $this->create_submission($assign1, $user4, $submissiontext);
739
 
740
        $submissiontext = 'My first submission';
741
        $submission = $this->create_submission($assign2, $user6, $submissiontext);
742
 
743
        $this->setUser($user5);
744
 
745
        $grade = '72.00';
746
        $teachercommenttext = 'This is better. Thanks.';
747
        $data = new \stdClass();
748
        $data->attemptnumber = 1;
749
        $data->grade = $grade;
750
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
751
 
752
        // Give the submission a grade.
753
        $assign1->save_grade($user4->id, $data);
754
 
755
        $this->setUser($user5);
756
 
757
        $grade = '81.00';
758
        $teachercommenttext = 'This is nice.';
759
        $data = new \stdClass();
760
        $data->attemptnumber = 1;
761
        $data->grade = $grade;
762
        $data->assignfeedbackcomments_editor = ['text' => $teachercommenttext, 'format' => FORMAT_MOODLE];
763
 
764
        // Give the submission a grade.
765
        $assign2->save_grade($user6->id, $data);
766
 
767
        // Check data is in place.
768
        $data = $DB->get_records('assign_submission');
769
        // We should have one entry for user 3 and two entries each for user 4 and 6.
770
        $this->assertCount(5, $data);
771
        $usercounts = [
772
            $user3->id => 0,
773
            $user4->id => 0,
774
            $user6->id => 0
775
        ];
776
        foreach ($data as $datum) {
777
            $usercounts[$datum->userid]++;
778
        }
779
        $this->assertEquals(1, $usercounts[$user3->id]);
780
        $this->assertEquals(2, $usercounts[$user4->id]);
781
        $this->assertEquals(2, $usercounts[$user6->id]);
782
 
783
        $data = $DB->get_records('assign_grades');
784
        // Two entries in assign_grades, one for each grade given.
785
        $this->assertCount(2, $data);
786
 
787
        $data = $DB->get_records('assign_overrides');
788
        $this->assertCount(1, $data);
789
 
790
        $data = $DB->get_records('comments');
791
        $this->assertCount(1, $data);
792
 
793
        $userlist = new \core_privacy\local\request\approved_userlist($context, 'assign', [$user1->id, $user2->id]);
794
        provider::delete_data_for_users($userlist);
795
 
796
        $data = $DB->get_records('assign_overrides');
797
        $this->assertEmpty($data);
798
 
799
        $data = $DB->get_records('comments');
800
        $this->assertEmpty($data);
801
 
802
        $data = $DB->get_records('assign_submission');
803
        // No change here.
804
        $this->assertCount(5, $data);
805
 
806
        $userlist = new \core_privacy\local\request\approved_userlist($context, 'assign', [$user3->id, $user5->id]);
807
        provider::delete_data_for_users($userlist);
808
 
809
        $data = $DB->get_records('assign_submission');
810
        // Only the record for user 3 has been deleted.
811
        $this->assertCount(4, $data);
812
 
813
        $data = $DB->get_records('assign_grades');
814
        // Grades should be unchanged.
815
        $this->assertCount(2, $data);
816
    }
817
}