Differences Between: [Versions 39 and 310]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Unit tests for assignfeedback_editpdf\comments_quick_list 19 * 20 * @package assignfeedback_editpdf 21 * @category phpunit 22 * @copyright 2013 Damyon Wiese 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 use \assignfeedback_editpdf\comments_quick_list; 29 use \assignfeedback_editpdf\document_services; 30 use \assignfeedback_editpdf\page_editor; 31 use \assignfeedback_editpdf\pdf; 32 use \assignfeedback_editpdf\comment; 33 use \assignfeedback_editpdf\annotation; 34 35 global $CFG; 36 require_once($CFG->dirroot . '/mod/assign/tests/generator.php'); 37 38 /** 39 * Unit tests for assignfeedback_editpdf\comments_quick_list 40 * 41 * @copyright 2013 Damyon Wiese 42 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 43 */ 44 class assignfeedback_editpdf_testcase extends advanced_testcase { 45 46 // Use the generator helper. 47 use mod_assign_test_generator; 48 49 /** 50 * Ensure that GS is available. 51 */ 52 protected function require_ghostscript() { 53 // Skip this test if ghostscript is not supported. 54 $result = pdf::test_gs_path(false); 55 if ($result->status !== assignfeedback_editpdf\pdf::GSPATH_OK) { 56 $this->markTestSkipped('Ghostscript not setup'); 57 } 58 } 59 60 protected function add_file_submission($student, $assign) { 61 global $CFG; 62 63 $this->setUser($student); 64 65 // Create a file submission with the test pdf. 66 $submission = $assign->get_user_submission($student->id, true); 67 68 $fs = get_file_storage(); 69 $pdfsubmission = (object) array( 70 'contextid' => $assign->get_context()->id, 71 'component' => 'assignsubmission_file', 72 'filearea' => ASSIGNSUBMISSION_FILE_FILEAREA, 73 'itemid' => $submission->id, 74 'filepath' => '/', 75 'filename' => 'submission.pdf' 76 ); 77 $sourcefile = $CFG->dirroot.'/mod/assign/feedback/editpdf/tests/fixtures/submission.pdf'; 78 $fs->create_file_from_pathname($pdfsubmission, $sourcefile); 79 80 $data = new stdClass(); 81 $plugin = $assign->get_submission_plugin_by_type('file'); 82 $plugin->save($submission, $data); 83 } 84 85 public function test_comments_quick_list() { 86 $this->resetAfterTest(); 87 $course = $this->getDataGenerator()->create_course(); 88 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); 89 90 $this->setUser($teacher); 91 92 $this->assertEmpty(comments_quick_list::get_comments()); 93 94 $comment = comments_quick_list::add_comment('test', 45, 'red'); 95 $comments = comments_quick_list::get_comments(); 96 $this->assertEquals(count($comments), 1); 97 $first = reset($comments); 98 $this->assertEquals($comment, $first); 99 100 $commentbyid = comments_quick_list::get_comment($comment->id); 101 $this->assertEquals($comment, $commentbyid); 102 103 $this->assertTrue(comments_quick_list::remove_comment($comment->id)); 104 105 $comments = comments_quick_list::get_comments(); 106 $this->assertEmpty($comments); 107 } 108 109 public function test_page_editor() { 110 $this->resetAfterTest(); 111 $course = $this->getDataGenerator()->create_course(); 112 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); 113 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 114 $assign = $this->create_instance($course, [ 115 'assignsubmission_onlinetext_enabled' => 1, 116 'assignsubmission_file_enabled' => 1, 117 'assignsubmission_file_maxfiles' => 1, 118 'assignfeedback_editpdf_enabled' => 1, 119 'assignsubmission_file_maxsizebytes' => 1000000, 120 ]); 121 122 // Add the standard submission. 123 $this->add_file_submission($student, $assign); 124 125 $this->setUser($teacher); 126 127 $grade = $assign->get_user_grade($student->id, true); 128 129 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 130 $this->assertFalse($notempty); 131 132 $comment = new comment(); 133 $comment->rawtext = 'Comment text'; 134 $comment->width = 100; 135 $comment->x = 100; 136 $comment->y = 100; 137 $comment->colour = 'red'; 138 139 $comment2 = new comment(); 140 $comment2->rawtext = 'Comment text 2'; 141 $comment2->width = 100; 142 $comment2->x = 200; 143 $comment2->y = 100; 144 $comment2->colour = 'clear'; 145 146 page_editor::set_comments($grade->id, 0, array($comment, $comment2)); 147 148 $annotation = new annotation(); 149 $annotation->path = ''; 150 $annotation->x = 100; 151 $annotation->y = 100; 152 $annotation->endx = 200; 153 $annotation->endy = 200; 154 $annotation->type = 'line'; 155 $annotation->colour = 'red'; 156 157 $annotation2 = new annotation(); 158 $annotation2->path = ''; 159 $annotation2->x = 100; 160 $annotation2->y = 100; 161 $annotation2->endx = 200; 162 $annotation2->endy = 200; 163 $annotation2->type = 'rectangle'; 164 $annotation2->colour = 'yellow'; 165 166 page_editor::set_annotations($grade->id, 0, array($annotation, $annotation2)); 167 168 // Still empty because all edits are still drafts. 169 $this->assertFalse(page_editor::has_annotations_or_comments($grade->id, false)); 170 171 $comments = page_editor::get_comments($grade->id, 0, false); 172 $this->assertEmpty($comments); 173 174 $comments = page_editor::get_comments($grade->id, 0, true); 175 $this->assertEquals(count($comments), 2); 176 177 $annotations = page_editor::get_annotations($grade->id, 0, false); 178 $this->assertEmpty($annotations); 179 180 $annotations = page_editor::get_annotations($grade->id, 0, true); 181 $this->assertEquals(count($annotations), 2); 182 183 $comment = reset($comments); 184 $annotation = reset($annotations); 185 186 page_editor::remove_comment($comment->id); 187 page_editor::remove_annotation($annotation->id); 188 189 $comments = page_editor::get_comments($grade->id, 0, true); 190 $this->assertEquals(count($comments), 1); 191 192 $annotations = page_editor::get_annotations($grade->id, 0, true); 193 $this->assertEquals(count($annotations), 1); 194 195 // Release the drafts. 196 page_editor::release_drafts($grade->id); 197 198 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 199 $this->assertTrue($notempty); 200 201 // Unrelease the drafts. 202 page_editor::unrelease_drafts($grade->id); 203 204 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 205 $this->assertFalse($notempty); 206 } 207 208 public function test_document_services() { 209 $this->require_ghostscript(); 210 $this->resetAfterTest(); 211 $course = $this->getDataGenerator()->create_course(); 212 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); 213 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 214 $assign = $this->create_instance($course, [ 215 'assignsubmission_onlinetext_enabled' => 1, 216 'assignsubmission_file_enabled' => 1, 217 'assignsubmission_file_maxfiles' => 1, 218 'assignfeedback_editpdf_enabled' => 1, 219 'assignsubmission_file_maxsizebytes' => 1000000, 220 ]); 221 222 // Add the standard submission. 223 $this->add_file_submission($student, $assign); 224 225 $this->setUser($teacher); 226 227 $grade = $assign->get_user_grade($student->id, true); 228 229 $contextid = $assign->get_context()->id; 230 $component = 'assignfeedback_editpdf'; 231 $filearea = document_services::COMBINED_PDF_FILEAREA; 232 $itemid = $grade->id; 233 $filepath = '/'; 234 $filename = document_services::COMBINED_PDF_FILENAME; 235 $fs = \get_file_storage(); 236 237 // Generate a blank combined pdf. 238 $record = new \stdClass(); 239 $record->contextid = $contextid; 240 $record->component = $component; 241 $record->filearea = $filearea; 242 $record->itemid = $itemid; 243 $record->filepath = $filepath; 244 $record->filename = $filename; 245 $fs->create_file_from_string($record, base64_decode(document_services::BLANK_PDF_BASE64)); 246 247 // Verify that the blank combined pdf has the expected hash. 248 $combinedpdf = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename); 249 $this->assertEquals($combinedpdf->get_contenthash(), document_services::BLANK_PDF_HASH); 250 251 // Generate page images and verify that the combined pdf has been replaced. 252 document_services::get_page_images_for_attempt($assign, $student->id, -1); 253 $combinedpdf = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename); 254 $this->assertNotEquals($combinedpdf->get_contenthash(), document_services::BLANK_PDF_HASH); 255 256 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 257 $this->assertFalse($notempty); 258 259 $comment = new comment(); 260 261 // Use some different charset in the comment text. 262 $comment->rawtext = 'Testing example: בקלות ואמנות'; 263 $comment->width = 100; 264 $comment->x = 100; 265 $comment->y = 100; 266 $comment->colour = 'red'; 267 268 page_editor::set_comments($grade->id, 0, array($comment)); 269 270 $annotations = array(); 271 272 $annotation = new annotation(); 273 $annotation->path = ''; 274 $annotation->x = 100; 275 $annotation->y = 100; 276 $annotation->endx = 200; 277 $annotation->endy = 200; 278 $annotation->type = 'line'; 279 $annotation->colour = 'red'; 280 array_push($annotations, $annotation); 281 282 $annotation = new annotation(); 283 $annotation->path = ''; 284 $annotation->x = 100; 285 $annotation->y = 100; 286 $annotation->endx = 200; 287 $annotation->endy = 200; 288 $annotation->type = 'rectangle'; 289 $annotation->colour = 'yellow'; 290 array_push($annotations, $annotation); 291 292 $annotation = new annotation(); 293 $annotation->path = ''; 294 $annotation->x = 100; 295 $annotation->y = 100; 296 $annotation->endx = 200; 297 $annotation->endy = 200; 298 $annotation->type = 'oval'; 299 $annotation->colour = 'green'; 300 array_push($annotations, $annotation); 301 302 $annotation = new annotation(); 303 $annotation->path = ''; 304 $annotation->x = 100; 305 $annotation->y = 100; 306 $annotation->endx = 200; 307 $annotation->endy = 116; 308 $annotation->type = 'highlight'; 309 $annotation->colour = 'blue'; 310 array_push($annotations, $annotation); 311 312 $annotation = new annotation(); 313 $annotation->path = '100,100:105,105:110,100'; 314 $annotation->x = 100; 315 $annotation->y = 100; 316 $annotation->endx = 110; 317 $annotation->endy = 105; 318 $annotation->type = 'pen'; 319 $annotation->colour = 'black'; 320 array_push($annotations, $annotation); 321 page_editor::set_annotations($grade->id, 0, $annotations); 322 323 page_editor::release_drafts($grade->id); 324 325 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 326 327 $this->assertTrue($notempty); 328 329 $file = document_services::generate_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); 330 $this->assertNotEmpty($file); 331 332 $file2 = document_services::get_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); 333 334 $this->assertEquals($file, $file2); 335 336 document_services::delete_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); 337 $file3 = document_services::get_feedback_document($assign->get_instance()->id, $grade->userid, $grade->attemptnumber); 338 339 $this->assertEmpty($file3); 340 } 341 342 public function test_conversion_task() { 343 global $DB; 344 $this->require_ghostscript(); 345 $this->resetAfterTest(); 346 cron_setup_user(); 347 348 $task = new \assignfeedback_editpdf\task\convert_submissions; 349 350 $course = $this->getDataGenerator()->create_course(); 351 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 352 $assignopts = [ 353 'assignsubmission_file_enabled' => 1, 354 'assignsubmission_file_maxfiles' => 1, 355 'assignfeedback_editpdf_enabled' => 1, 356 'assignsubmission_file_maxsizebytes' => 1000000, 357 ]; 358 $assign = $this->create_instance($course, $assignopts); 359 360 // Add the standard submission. 361 $this->add_file_submission($student, $assign); 362 363 // Run the conversion task. 364 ob_start(); 365 $task->execute(); 366 $output = ob_get_clean(); 367 368 // Verify it acted on both submissions in the queue. 369 $this->assertStringContainsString("Convert 1 submission attempt(s) for assignment {$assign->get_instance()->id}", $output); 370 $this->assertEquals(0, $DB->count_records('assignfeedback_editpdf_queue')); 371 372 // Set a known limit. 373 set_config('conversionattemptlimit', 3); 374 375 // Trigger a re-queue by 'updating' a submission. 376 $submission = $assign->get_user_submission($student->id, true); 377 $plugin = $assign->get_submission_plugin_by_type('file'); 378 $plugin->save($submission, (new stdClass)); 379 380 // Verify that queued a conversion task. 381 $this->assertEquals(1, $DB->count_records('assignfeedback_editpdf_queue')); 382 383 // Fake some failed attempts for it. 384 $queuerecord = $DB->get_record('assignfeedback_editpdf_queue', ['submissionid' => $submission->id]); 385 $queuerecord->attemptedconversions = 3; 386 $DB->update_record('assignfeedback_editpdf_queue', $queuerecord); 387 388 ob_start(); 389 $task->execute(); 390 $output = ob_get_clean(); 391 392 // Verify that the cron task skipped the submission. 393 $this->assertStringNotContainsString("Convert 1 submission attempt(s) for assignment {$assign->get_instance()->id}", $output); 394 // And it removed it from the queue. 395 $this->assertEquals(0, $DB->count_records('assignfeedback_editpdf_queue')); 396 397 } 398 399 /** 400 * Test that modifying the annotated pdf form return true when modified 401 * and false when not modified. 402 */ 403 public function test_is_feedback_modified() { 404 $this->resetAfterTest(); 405 $course = $this->getDataGenerator()->create_course(); 406 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); 407 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 408 $assign = $this->create_instance($course, [ 409 'assignsubmission_onlinetext_enabled' => 1, 410 'assignsubmission_file_enabled' => 1, 411 'assignsubmission_file_maxfiles' => 1, 412 'assignfeedback_editpdf_enabled' => 1, 413 'assignsubmission_file_maxsizebytes' => 1000000, 414 ]); 415 416 // Add the standard submission. 417 $this->add_file_submission($student, $assign); 418 419 $this->setUser($teacher); 420 $grade = $assign->get_user_grade($student->id, true); 421 422 $notempty = page_editor::has_annotations_or_comments($grade->id, false); 423 $this->assertFalse($notempty); 424 425 $comment = new comment(); 426 427 $comment->rawtext = 'Comment text'; 428 $comment->width = 100; 429 $comment->x = 100; 430 $comment->y = 100; 431 $comment->colour = 'red'; 432 433 page_editor::set_comments($grade->id, 0, array($comment)); 434 435 $annotations = array(); 436 437 $annotation = new annotation(); 438 $annotation->path = ''; 439 $annotation->x = 100; 440 $annotation->y = 100; 441 $annotation->endx = 200; 442 $annotation->endy = 200; 443 $annotation->type = 'line'; 444 $annotation->colour = 'red'; 445 array_push($annotations, $annotation); 446 447 page_editor::set_annotations($grade->id, 0, $annotations); 448 449 $plugin = $assign->get_feedback_plugin_by_type('editpdf'); 450 $data = new stdClass(); 451 $data->editpdf_source_userid = $student->id; 452 $this->assertTrue($plugin->is_feedback_modified($grade, $data)); 453 $plugin->save($grade, $data); 454 455 $annotation = new annotation(); 456 $annotation->gradeid = $grade->id; 457 $annotation->pageno = 0; 458 $annotation->path = ''; 459 $annotation->x = 100; 460 $annotation->y = 100; 461 $annotation->endx = 200; 462 $annotation->endy = 200; 463 $annotation->type = 'rectangle'; 464 $annotation->colour = 'yellow'; 465 466 $yellowannotationid = page_editor::add_annotation($annotation); 467 468 // Add a comment as well. 469 $comment = new comment(); 470 $comment->gradeid = $grade->id; 471 $comment->pageno = 0; 472 $comment->rawtext = 'Second Comment text'; 473 $comment->width = 100; 474 $comment->x = 100; 475 $comment->y = 100; 476 $comment->colour = 'red'; 477 page_editor::add_comment($comment); 478 479 $this->assertTrue($plugin->is_feedback_modified($grade, $data)); 480 $plugin->save($grade, $data); 481 482 // We should have two annotations. 483 $this->assertCount(2, page_editor::get_annotations($grade->id, 0, false)); 484 // And two comments. 485 $this->assertCount(2, page_editor::get_comments($grade->id, 0, false)); 486 487 // Add one annotation and delete another. 488 $annotation = new annotation(); 489 $annotation->gradeid = $grade->id; 490 $annotation->pageno = 0; 491 $annotation->path = '100,100:105,105:110,100'; 492 $annotation->x = 100; 493 $annotation->y = 100; 494 $annotation->endx = 110; 495 $annotation->endy = 105; 496 $annotation->type = 'pen'; 497 $annotation->colour = 'black'; 498 page_editor::add_annotation($annotation); 499 500 $annotations = page_editor::get_annotations($grade->id, 0, true); 501 page_editor::remove_annotation($yellowannotationid); 502 $this->assertTrue($plugin->is_feedback_modified($grade, $data)); 503 $plugin->save($grade, $data); 504 505 // We should have two annotations. 506 $this->assertCount(2, page_editor::get_annotations($grade->id, 0, false)); 507 // And two comments. 508 $this->assertCount(2, page_editor::get_comments($grade->id, 0, false)); 509 510 // Add a comment and then remove it. Should not be considered as modified. 511 $comment = new comment(); 512 $comment->gradeid = $grade->id; 513 $comment->pageno = 0; 514 $comment->rawtext = 'Third Comment text'; 515 $comment->width = 400; 516 $comment->x = 57; 517 $comment->y = 205; 518 $comment->colour = 'black'; 519 $comment->id = page_editor::add_comment($comment); 520 521 // We should now have three comments. 522 $this->assertCount(3, page_editor::get_comments($grade->id, 0, true)); 523 // Now delete the newest record. 524 page_editor::remove_comment($comment->id); 525 // Back to two comments. 526 $this->assertCount(2, page_editor::get_comments($grade->id, 0, true)); 527 // No modification. 528 $this->assertFalse($plugin->is_feedback_modified($grade, $data)); 529 } 530 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body