Differences Between: [Versions 311 and 403] [Versions 400 and 403] [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 * 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 */ 82 public function test_get_contexts_for_userid() { 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 */ 154 public function test_get_users_in_context() { 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 */ 243 public function test_export_user_data_student() { 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 */ 338 public function test_export_user_data_teacher() { 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 */ 447 public function test_delete_data_for_all_users_in_context() { 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 */ 550 public function test_delete_data_for_user() { 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 */ 675 public function test_delete_data_for_users() { 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body