[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 (some of) mod/assign/locallib.php. 19 * 20 * @package mod_assign 21 * @category phpunit 22 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 require_once($CFG->dirroot . '/mod/assign/locallib.php'); 31 require_once($CFG->dirroot . '/mod/assign/upgradelib.php'); 32 require_once($CFG->dirroot . '/mod/assign/tests/base_test.php'); 33 34 /** 35 * Unit tests for (some of) mod/assign/locallib.php. 36 * 37 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class mod_assign_locallib_testcase extends mod_assign_base_testcase { 41 42 public function test_return_links() { 43 global $PAGE; 44 $this->setUser($this->editingteachers[0]); 45 $returnaction = 'RETURNACTION'; 46 $returnparams = array('param'=>'1'); 47 $assign = $this->create_instance(); 48 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 49 $assign->register_return_link($returnaction, $returnparams); 50 $this->assertEquals($returnaction, $assign->get_return_action()); 51 $this->assertEquals($returnparams, $assign->get_return_params()); 52 } 53 54 public function test_get_feedback_plugins() { 55 $this->setUser($this->editingteachers[0]); 56 $assign = $this->create_instance(); 57 $installedplugins = array_keys(core_component::get_plugin_list('assignfeedback')); 58 59 foreach ($assign->get_feedback_plugins() as $plugin) { 60 $this->assertContains($plugin->get_type(), $installedplugins, 'Feedback plugin not in list of installed plugins'); 61 } 62 } 63 64 public function test_get_submission_plugins() { 65 $this->setUser($this->editingteachers[0]); 66 $assign = $this->create_instance(); 67 $installedplugins = array_keys(core_component::get_plugin_list('assignsubmission')); 68 69 foreach ($assign->get_submission_plugins() as $plugin) { 70 $this->assertContains($plugin->get_type(), $installedplugins, 'Submission plugin not in list of installed plugins'); 71 } 72 } 73 74 public function test_is_blind_marking() { 75 $this->setUser($this->editingteachers[0]); 76 $assign = $this->create_instance(array('blindmarking'=>1)); 77 $this->assertEquals(true, $assign->is_blind_marking()); 78 79 // Test cannot see student names. 80 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 81 $output = $assign->get_renderer()->render($gradingtable); 82 $this->assertEquals(true, strpos($output, get_string('hiddenuser', 'assign'))); 83 84 // Test students cannot reveal identities. 85 $nopermission = false; 86 $this->students[0]->ignoresesskey = true; 87 $this->setUser($this->students[0]); 88 $this->setExpectedException('required_capability_exception'); 89 $assign->reveal_identities(); 90 $this->students[0]->ignoresesskey = false; 91 92 // Test teachers cannot reveal identities. 93 $nopermission = false; 94 $this->teachers[0]->ignoresesskey = true; 95 $this->setUser($this->teachers[0]); 96 $this->setExpectedException('required_capability_exception'); 97 $assign->reveal_identities(); 98 $this->teachers[0]->ignoresesskey = false; 99 100 // Test sesskey is required. 101 $this->setUser($this->editingteachers[0]); 102 $this->setExpectedException('moodle_exception'); 103 $assign->reveal_identities(); 104 105 // Test editingteacher can reveal identities if sesskey is ignored. 106 $this->editingteachers[0]->ignoresesskey = true; 107 $this->setUser($this->editingteachers[0]); 108 $assign->reveal_identities(); 109 $this->assertEquals(false, $assign->is_blind_marking()); 110 $this->editingteachers[0]->ignoresesskey = false; 111 112 // Test student names are visible. 113 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 114 $output = $assign->get_renderer()->render($gradingtable); 115 $this->assertEquals(false, strpos($output, get_string('hiddenuser', 'assign'))); 116 117 // Set this back to default. 118 $this->editingteachers[0]->ignoresesskey = false; 119 } 120 121 /** 122 * Test submissions with extension date. 123 */ 124 public function test_gradingtable_extension_due_date() { 125 global $PAGE; 126 127 // Setup the assignment. 128 $this->create_extra_users(); 129 $this->setUser($this->editingteachers[0]); 130 $assign = $this->create_instance(array( 131 'assignsubmission_onlinetext_enabled'=>1, 132 'duedate' => time() - 4 * 24 * 60 * 60, 133 )); 134 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array( 135 'id' => $assign->get_course_module()->id, 136 'action' => 'grading', 137 ))); 138 139 // Check that the assignment is late. 140 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 141 $output = $assign->get_renderer()->render($gradingtable); 142 $this->assertContains(get_string('submissionstatus_', 'assign'), $output); 143 $this->assertContains(get_string('overdue', 'assign', format_time(4*24*60*60)), $output); 144 145 // Grant an extension. 146 $extendedtime = time() + 2 * 24 * 60 * 60; 147 $assign->testable_save_user_extension($this->students[0]->id, $extendedtime); 148 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 149 $output = $assign->get_renderer()->render($gradingtable); 150 $this->assertContains(get_string('submissionstatus_', 'assign'), $output); 151 $this->assertContains(get_string('userextensiondate', 'assign', userdate($extendedtime)), $output); 152 153 // Simulate a submission. 154 $this->setUser($this->students[0]); 155 $submission = $assign->get_user_submission($this->students[0]->id, true); 156 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 157 $assign->testable_update_submission($submission, $this->students[0]->id, true, false); 158 $data = new stdClass(); 159 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 160 'text'=>'Submission text', 161 'format'=>FORMAT_MOODLE); 162 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 163 $plugin->save($submission, $data); 164 165 // Verify output. 166 $this->setUser($this->editingteachers[0]); 167 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 168 $output = $assign->get_renderer()->render($gradingtable); 169 $this->assertContains(get_string('submissionstatus_submitted', 'assign'), $output); 170 $this->assertContains(get_string('userextensiondate', 'assign', userdate($extendedtime)), $output); 171 } 172 173 /** 174 * Test that late submissions with extension date calculate correctly. 175 */ 176 public function test_gradingtable_extension_date_calculation_for_lateness() { 177 global $PAGE; 178 179 // Setup the assignment. 180 $this->create_extra_users(); 181 $this->setUser($this->editingteachers[0]); 182 $time = time(); 183 $assign = $this->create_instance(array( 184 'assignsubmission_onlinetext_enabled'=>1, 185 'duedate' => $time - 4 * 24 * 60 * 60, 186 )); 187 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array( 188 'id' => $assign->get_course_module()->id, 189 'action' => 'grading', 190 ))); 191 192 // Check that the assignment is late. 193 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 194 $output = $assign->get_renderer()->render($gradingtable); 195 $this->assertContains(get_string('submissionstatus_', 'assign'), $output); 196 $difftime = time() - $time; 197 $this->assertContains(get_string('overdue', 'assign', format_time(4*24*60*60 + $difftime)), $output); 198 199 // Grant an extension that is in the past. 200 $assign->testable_save_user_extension($this->students[0]->id, $time - 2 * 24 * 60 * 60); 201 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 202 $output = $assign->get_renderer()->render($gradingtable); 203 $this->assertContains(get_string('submissionstatus_', 'assign'), $output); 204 $this->assertContains(get_string('userextensiondate', 'assign', userdate($time - 2*24*60*60)), $output); 205 $difftime = time() - $time; 206 $this->assertContains(get_string('overdue', 'assign', format_time(2*24*60*60 + $difftime)), $output); 207 208 // Simulate a submission. 209 $this->setUser($this->students[0]); 210 $submission = $assign->get_user_submission($this->students[0]->id, true); 211 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 212 $assign->testable_update_submission($submission, $this->students[0]->id, true, false); 213 $data = new stdClass(); 214 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 215 'text'=>'Submission text', 216 'format'=>FORMAT_MOODLE); 217 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 218 $plugin->save($submission, $data); 219 $submittedtime = time(); 220 221 // Verify output. 222 $this->setUser($this->editingteachers[0]); 223 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 224 $output = $assign->get_renderer()->render($gradingtable); 225 $this->assertContains(get_string('submissionstatus_submitted', 'assign'), $output); 226 $this->assertContains(get_string('userextensiondate', 'assign', userdate($time - 2*24*60*60)), $output); 227 228 $difftime = $submittedtime - $time; 229 $this->assertContains(get_string('submittedlateshort', 'assign', format_time(2*24*60*60 + $difftime)), $output); 230 } 231 232 /** 233 * Check that group submission information is rendered correctly in the 234 * grading table. 235 */ 236 public function test_gradingtable_group_submissions_rendering() { 237 global $PAGE; 238 239 $this->create_extra_users(); 240 // Now verify group assignments. 241 $this->setUser($this->teachers[0]); 242 $assign = $this->create_instance(array( 243 'teamsubmission' => 1, 244 'assignsubmission_onlinetext_enabled' => 1, 245 'submissiondrafts' => 1, 246 'requireallteammemberssubmit' => 0, 247 )); 248 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array( 249 'id' => $assign->get_course_module()->id, 250 'action' => 'grading', 251 ))); 252 253 // Add a submission. 254 $this->setUser($this->extrastudents[0]); 255 $data = new stdClass(); 256 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 257 'text'=>'Submission text', 258 'format'=>FORMAT_MOODLE); 259 $notices = array(); 260 $assign->save_submission($data, $notices); 261 262 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true); 263 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 264 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true); 265 266 // Check output. 267 $this->setUser($this->teachers[0]); 268 $gradingtable = new assign_grading_table($assign, 4, '', 0, true); 269 $output = $assign->get_renderer()->render($gradingtable); 270 $document = new DOMDocument(); 271 $document->loadHTML($output); 272 $xpath = new DOMXPath($document); 273 274 // Check status. 275 $this->assertSame(get_string('submissionstatus_submitted', 'assign'), $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c4"]/div[@class="submissionstatussubmitted"])')); 276 $this->assertSame(get_string('submissionstatus_submitted', 'assign'), $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c4"]/div[@class="submissionstatussubmitted"])')); 277 278 // Check submission last modified date 279 $this->assertGreaterThan(0, strtotime($xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c8"])'))); 280 $this->assertGreaterThan(0, strtotime($xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c8"])'))); 281 282 // Check group. 283 $this->assertSame($this->groups[0]->name, $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c5"])')); 284 $this->assertSame($this->groups[0]->name, $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c5"])')); 285 286 // Check submission text. 287 $this->assertSame('Submission text', $xpath->evaluate('string(//td[@id="mod_assign_grading_r0_c9"]/div/div)')); 288 $this->assertSame('Submission text', $xpath->evaluate('string(//td[@id="mod_assign_grading_r3_c9"]/div/div)')); 289 290 // Check comments can be made. 291 $this->assertSame(1, (int)$xpath->evaluate('count(//td[@id="mod_assign_grading_r0_c10"]//textarea)')); 292 $this->assertSame(1, (int)$xpath->evaluate('count(//td[@id="mod_assign_grading_r3_c10"]//textarea)')); 293 } 294 295 public function test_show_intro() { 296 // Test whether we are showing the intro at the correct times. 297 $this->setUser($this->editingteachers[0]); 298 $assign = $this->create_instance(array('alwaysshowdescription'=>1)); 299 300 $this->assertEquals(true, $assign->testable_show_intro()); 301 302 $tomorrow = time() + (24*60*60); 303 304 $assign = $this->create_instance(array('alwaysshowdescription'=>0, 305 'allowsubmissionsfromdate'=>$tomorrow)); 306 $this->assertEquals(false, $assign->testable_show_intro()); 307 $yesterday = time() - (24*60*60); 308 $assign = $this->create_instance(array('alwaysshowdescription'=>0, 309 'allowsubmissionsfromdate'=>$yesterday)); 310 $this->assertEquals(true, $assign->testable_show_intro()); 311 } 312 313 public function test_has_submissions_or_grades() { 314 $this->setUser($this->editingteachers[0]); 315 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1)); 316 317 $instance = $assign->get_instance(); 318 319 // Should start empty. 320 $this->assertEquals(false, $assign->has_submissions_or_grades()); 321 322 // Simulate a submission. 323 $this->setUser($this->students[0]); 324 $submission = $assign->get_user_submission($this->students[0]->id, true); 325 $data = new stdClass(); 326 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 327 'text'=>'Submission text', 328 'format'=>FORMAT_MOODLE); 329 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 330 $plugin->save($submission, $data); 331 332 // Now test again. 333 $this->assertEquals(true, $assign->has_submissions_or_grades()); 334 // Set this back to default. 335 $this->students[0]->ignoresesskey = false; 336 } 337 338 public function test_delete_grades() { 339 $this->setUser($this->editingteachers[0]); 340 $assign = $this->create_instance(); 341 342 // Simulate adding a grade. 343 $this->setUser($this->teachers[0]); 344 $data = new stdClass(); 345 $data->grade = '50.0'; 346 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 347 348 // Now see if the data is in the gradebook. 349 $gradinginfo = grade_get_grades($this->course->id, 350 'mod', 351 'assign', 352 $assign->get_instance()->id); 353 354 $this->assertNotEquals(0, count($gradinginfo->items)); 355 356 $assign->testable_delete_grades(); 357 $gradinginfo = grade_get_grades($this->course->id, 358 'mod', 359 'assign', 360 $assign->get_instance()->id); 361 362 $this->assertEquals(0, count($gradinginfo->items)); 363 } 364 365 public function test_delete_instance() { 366 $this->setUser($this->editingteachers[0]); 367 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1)); 368 369 // Simulate adding a grade. 370 $this->setUser($this->teachers[0]); 371 $data = new stdClass(); 372 $data->grade = '50.0'; 373 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 374 375 // Simulate a submission. 376 $this->setUser($this->students[0]); 377 $submission = $assign->get_user_submission($this->students[0]->id, true); 378 $data = new stdClass(); 379 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 380 'text'=>'Submission text', 381 'format'=>FORMAT_MOODLE); 382 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 383 $plugin->save($submission, $data); 384 385 // Now try and delete. 386 $this->assertEquals(true, $assign->delete_instance()); 387 } 388 389 public function test_reset_userdata() { 390 global $DB; 391 392 $now = time(); 393 $this->setUser($this->editingteachers[0]); 394 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 395 'duedate'=>$now)); 396 397 // Simulate adding a grade. 398 $this->setUser($this->teachers[0]); 399 $data = new stdClass(); 400 $data->grade = '50.0'; 401 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 402 403 // Simulate a submission. 404 $this->setUser($this->students[0]); 405 $submission = $assign->get_user_submission($this->students[0]->id, true); 406 $data = new stdClass(); 407 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 408 'text'=>'Submission text', 409 'format'=>FORMAT_MOODLE); 410 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 411 $plugin->save($submission, $data); 412 413 $this->assertEquals(true, $assign->has_submissions_or_grades()); 414 // Now try and reset. 415 $data = new stdClass(); 416 $data->reset_assign_submissions = 1; 417 $data->reset_gradebook_grades = 1; 418 $data->courseid = $this->course->id; 419 $data->timeshift = 24*60*60; 420 $this->setUser($this->editingteachers[0]); 421 $assign->reset_userdata($data); 422 $this->assertEquals(false, $assign->has_submissions_or_grades()); 423 424 // Reload the instance data. 425 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id)); 426 $this->assertEquals($now + 24*60*60, $instance->duedate); 427 428 // Test reset using assign_reset_userdata(). 429 $assignduedate = $instance->duedate; // Keep old updated value for comparison. 430 $data->timeshift = 2*24*60*60; 431 assign_reset_userdata($data); 432 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id)); 433 $this->assertEquals($assignduedate + 2*24*60*60, $instance->duedate); 434 435 // Create one more assignment and reset, make sure time shifted for previous assignment is not changed. 436 $assign2 = $this->create_instance(array('assignsubmission_onlinetext_enabled' => 1, 437 'duedate' => $now)); 438 $assignduedate = $instance->duedate; 439 $data->timeshift = 3*24*60*60; 440 $assign2->reset_userdata($data); 441 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id)); 442 $this->assertEquals($assignduedate, $instance->duedate); 443 $instance2 = $DB->get_record('assign', array('id' => $assign2->get_instance()->id)); 444 $this->assertEquals($now + 3*24*60*60, $instance2->duedate); 445 446 // Reset both assignments using assign_reset_userdata() and make sure both assignments have same date. 447 $assignduedate = $instance->duedate; 448 $assign2duedate = $instance2->duedate; 449 $data->timeshift = 4*24*60*60; 450 assign_reset_userdata($data); 451 $instance = $DB->get_record('assign', array('id' => $assign->get_instance()->id)); 452 $this->assertEquals($assignduedate + 4*24*60*60, $instance->duedate); 453 $instance2 = $DB->get_record('assign', array('id' => $assign2->get_instance()->id)); 454 $this->assertEquals($assign2duedate + 4*24*60*60, $instance2->duedate); 455 } 456 457 public function test_plugin_settings() { 458 global $DB; 459 460 $now = time(); 461 $this->setUser($this->editingteachers[0]); 462 $assign = $this->create_instance(array('assignsubmission_file_enabled'=>1, 463 'assignsubmission_file_maxfiles'=>12, 464 'assignsubmission_file_maxsizebytes'=>10)); 465 466 $plugin = $assign->get_submission_plugin_by_type('file'); 467 $this->assertEquals('12', $plugin->get_config('maxfilesubmissions')); 468 } 469 470 public function test_update_calendar() { 471 global $DB; 472 473 $this->setUser($this->editingteachers[0]); 474 $userctx = context_user::instance($this->editingteachers[0]->id)->id; 475 476 // Hack to pretend that there was an editor involved. We need both $_POST and $_REQUEST, and a sesskey. 477 $draftid = file_get_unused_draft_itemid(); 478 $_REQUEST['introeditor'] = $draftid; 479 $_POST['introeditor'] = $draftid; 480 $_POST['sesskey'] = sesskey(); 481 482 // Write links to a draft area. 483 $fakearealink1 = file_rewrite_pluginfile_urls('<a href="@@PLUGINFILE@@/pic.gif">link</a>', 'draftfile.php', $userctx, 484 'user', 'draft', $draftid); 485 $fakearealink2 = file_rewrite_pluginfile_urls('<a href="@@PLUGINFILE@@/pic.gif">new</a>', 'draftfile.php', $userctx, 486 'user', 'draft', $draftid); 487 488 // Create a new assignment with links to a draft area. 489 $now = time(); 490 $assign = $this->create_instance(array( 491 'duedate' => $now, 492 'intro' => $fakearealink1, 493 'introformat' => FORMAT_HTML 494 )); 495 496 // See if there is an event in the calendar. 497 $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id); 498 $event = $DB->get_record('event', $params); 499 $this->assertNotEmpty($event); 500 $this->assertSame('link', $event->description); // The pluginfile links are removed. 501 502 // Make sure the same works when updating the assignment. 503 $instance = $assign->get_instance(); 504 $instance->instance = $instance->id; 505 $instance->intro = $fakearealink2; 506 $instance->introformat = FORMAT_HTML; 507 $assign->update_instance($instance); 508 $params = array('modulename' => 'assign', 'instance' => $assign->get_instance()->id); 509 $event = $DB->get_record('event', $params); 510 $this->assertNotEmpty($event); 511 $this->assertSame('new', $event->description); // The pluginfile links are removed. 512 513 // Create an assignment with a description that should be hidden. 514 $assign = $this->create_instance(array('duedate'=>$now + 160, 515 'alwaysshowdescription'=>false, 516 'allowsubmissionsfromdate'=>$now + 60, 517 'intro'=>'Some text')); 518 519 // Get the event from the calendar. 520 $params = array('modulename'=>'assign', 'instance'=>$assign->get_instance()->id); 521 $event = $DB->get_record('event', $params); 522 523 $this->assertEmpty($event->description); 524 525 // Change the allowsubmissionfromdate to the past - do this directly in the DB 526 // because if we call the assignment update method - it will update the calendar 527 // and we want to test that this works from cron. 528 $DB->set_field('assign', 'allowsubmissionsfromdate', $now - 60, array('id'=>$assign->get_instance()->id)); 529 // Run cron to update the event in the calendar. 530 assign::cron(); 531 $event = $DB->get_record('event', $params); 532 533 $this->assertContains('Some text', $event->description); 534 535 } 536 537 public function test_update_instance() { 538 global $DB; 539 540 $this->setUser($this->editingteachers[0]); 541 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1)); 542 543 $now = time(); 544 $instance = $assign->get_instance(); 545 $instance->duedate = $now; 546 $instance->instance = $instance->id; 547 $instance->assignsubmission_onlinetext_enabled = 1; 548 549 $assign->update_instance($instance); 550 551 $instance = $DB->get_record('assign', array('id'=>$assign->get_instance()->id)); 552 $this->assertEquals($now, $instance->duedate); 553 } 554 555 public function test_cannot_submit_empty() { 556 global $PAGE; 557 558 $this->setUser($this->editingteachers[0]); 559 $assign = $this->create_instance(array('submissiondrafts'=>1)); 560 561 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 562 563 // Test you cannot see the submit button for an offline assignment regardless. 564 $this->setUser($this->students[0]); 565 $output = $assign->view_student_summary($this->students[0], true); 566 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Can submit empty offline assignment'); 567 568 // Test you cannot see the submit button for an online text assignment with no submission. 569 $this->setUser($this->editingteachers[0]); 570 $instance = $assign->get_instance(); 571 $instance->instance = $instance->id; 572 $instance->assignsubmission_onlinetext_enabled = 1; 573 574 $assign->update_instance($instance); 575 $this->setUser($this->students[0]); 576 $output = $assign->view_student_summary($this->students[0], true); 577 $this->assertNotContains(get_string('submitassignment', 'assign'), $output, 'Cannot submit empty onlinetext assignment'); 578 579 // Simulate a submission. 580 $submission = $assign->get_user_submission($this->students[0]->id, true); 581 $data = new stdClass(); 582 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 583 'text'=>'Submission text', 584 'format'=>FORMAT_MOODLE); 585 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 586 $plugin->save($submission, $data); 587 // Test you can see the submit button for an online text assignment with a submission. 588 $output = $assign->view_student_summary($this->students[0], true); 589 $this->assertContains(get_string('submitassignment', 'assign'), $output, 'Can submit non empty onlinetext assignment'); 590 } 591 592 public function test_list_participants() { 593 global $CFG, $DB; 594 595 $this->create_extra_users(); 596 $this->setUser($this->editingteachers[0]); 597 $assign = $this->create_instance(array('grade'=>100)); 598 599 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true))); 600 601 // Teacher with user preference set should see suspended users as well. 602 set_user_preference('grade_report_showonlyactiveenrol', false); 603 $assign = $this->create_instance(array('grade'=>100)); 604 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT, 605 count($assign->list_participants(null, true))); 606 607 // Non-editing teacher should not see suspended users, even if user preference is set. 608 $this->setUser($this->teachers[0]); 609 set_user_preference('grade_report_showonlyactiveenrol', false); 610 $assign = $this->create_instance(array('grade'=>100)); 611 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($assign->list_participants(null, true))); 612 613 // Turn on availability and a group restriction, and check that it doesn't 614 // show users who aren't in the group. 615 $CFG->enableavailability = true; 616 $specialgroup = $this->getDataGenerator()->create_group( 617 array('courseid' => $this->course->id)); 618 $assign = $this->create_instance(array('grade' => 100, 619 'availability' => json_encode(\core_availability\tree::get_root_json( 620 array(\availability_group\condition::get_json($specialgroup->id)))))); 621 groups_add_member($specialgroup, $this->students[0]); 622 groups_add_member($specialgroup, $this->students[1]); 623 $this->assertEquals(2, count($assign->list_participants(null, true))); 624 } 625 626 public function test_count_teams() { 627 $this->create_extra_users(); 628 $this->setUser($this->editingteachers[0]); 629 $assign = $this->create_instance(array('teamsubmission'=>1)); 630 631 $this->assertEquals(self::GROUP_COUNT + 1, $assign->count_teams()); 632 } 633 634 public function test_submit_to_default_group() { 635 global $DB; 636 637 $this->preventResetByRollback(); 638 $sink = $this->redirectMessages(); 639 640 $this->setUser($this->editingteachers[0]); 641 $params = array('teamsubmission' => 1, 642 'assignsubmission_onlinetext_enabled' => 1, 643 'submissiondrafts'=>0); 644 $assign = $this->create_instance($params); 645 646 $newstudent = $this->getDataGenerator()->create_user(); 647 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 648 $this->getDataGenerator()->enrol_user($newstudent->id, 649 $this->course->id, 650 $studentrole->id); 651 $this->setUser($newstudent); 652 $data = new stdClass(); 653 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 654 'text'=>'Submission text', 655 'format'=>FORMAT_MOODLE); 656 $notices = array(); 657 658 $group = $assign->get_submission_group($newstudent->id); 659 $this->assertFalse($group, 'New student is in default group'); 660 $assign->save_submission($data, $notices); 661 $this->assertEmpty($notices, 'No errors on save submission'); 662 663 $sink->close(); 664 } 665 666 public function test_count_submissions() { 667 $this->create_extra_users(); 668 $this->setUser($this->editingteachers[0]); 669 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1)); 670 671 // Simulate a submission. 672 $this->setUser($this->extrastudents[0]); 673 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true); 674 $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT; 675 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false); 676 // Leave this one as DRAFT. 677 $data = new stdClass(); 678 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 679 'text'=>'Submission text', 680 'format'=>FORMAT_MOODLE); 681 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 682 $plugin->save($submission, $data); 683 684 // Simulate adding a grade. 685 $this->setUser($this->teachers[0]); 686 $data = new stdClass(); 687 $data->grade = '50.0'; 688 $assign->testable_apply_grade_to_user($data, $this->extrastudents[0]->id, 0); 689 690 // Simulate a submission. 691 $this->setUser($this->extrastudents[1]); 692 $submission = $assign->get_user_submission($this->extrastudents[1]->id, true); 693 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 694 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, false); 695 $data = new stdClass(); 696 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 697 'text'=>'Submission text', 698 'format'=>FORMAT_MOODLE); 699 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 700 $plugin->save($submission, $data); 701 702 // Simulate a submission. 703 $this->setUser($this->extrastudents[2]); 704 $submission = $assign->get_user_submission($this->extrastudents[2]->id, true); 705 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 706 $assign->testable_update_submission($submission, $this->extrastudents[2]->id, true, false); 707 $data = new stdClass(); 708 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 709 'text'=>'Submission text', 710 'format'=>FORMAT_MOODLE); 711 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 712 $plugin->save($submission, $data); 713 714 // Simulate a submission. 715 $this->setUser($this->extrastudents[3]); 716 $submission = $assign->get_user_submission($this->extrastudents[3]->id, true); 717 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 718 $assign->testable_update_submission($submission, $this->extrastudents[3]->id, true, false); 719 $data = new stdClass(); 720 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 721 'text'=>'Submission text', 722 'format'=>FORMAT_MOODLE); 723 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 724 $plugin->save($submission, $data); 725 726 // Simulate a submission for suspended user, this will never be counted. 727 $this->setUser($this->extrastudents[3]); 728 $submission = $assign->get_user_submission($this->extrasuspendedstudents[0]->id, true); 729 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 730 $assign->testable_update_submission($submission, $this->extrasuspendedstudents[0]->id, true, false); 731 $data = new stdClass(); 732 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 733 'text'=>'Submission text', 734 'format'=>FORMAT_MOODLE); 735 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 736 $plugin->save($submission, $data); 737 738 // Simulate adding a grade. 739 $this->setUser($this->teachers[0]); 740 $data = new stdClass(); 741 $data->grade = '50.0'; 742 $assign->testable_apply_grade_to_user($data, $this->extrastudents[3]->id, 0); 743 $assign->testable_apply_grade_to_user($data, $this->extrasuspendedstudents[0]->id, 0); 744 745 $this->assertEquals(2, $assign->count_grades()); 746 $this->assertEquals(4, $assign->count_submissions()); 747 $this->assertEquals(2, $assign->count_submissions_need_grading()); 748 $this->assertEquals(3, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED)); 749 $this->assertEquals(1, $assign->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT)); 750 } 751 752 public function test_get_grading_userid_list() { 753 $this->create_extra_users(); 754 $this->setUser($this->editingteachers[0]); 755 $assign = $this->create_instance(); 756 757 $users = $assign->testable_get_grading_userid_list(); 758 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT, count($users)); 759 760 $this->setUser($this->editingteachers[0]); 761 set_user_preference('grade_report_showonlyactiveenrol', false); 762 $assign = $this->create_instance(); 763 764 $users = $assign->testable_get_grading_userid_list(); 765 $this->assertEquals(self::DEFAULT_STUDENT_COUNT + self::EXTRA_STUDENT_COUNT + self::EXTRA_SUSPENDED_COUNT, count($users)); 766 } 767 768 public function test_cron() { 769 // First run cron so there are no messages waiting to be sent (from other tests). 770 cron_setup_user(); 771 assign::cron(); 772 773 // Now create an assignment and add some feedback. 774 $this->setUser($this->editingteachers[0]); 775 $assign = $this->create_instance(array('sendstudentnotifications'=>1)); 776 777 // Simulate adding a grade. 778 $this->setUser($this->teachers[0]); 779 $data = new stdClass(); 780 $data->grade = '50.0'; 781 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 782 $assign->testable_apply_grade_to_user($data, $this->students[1]->id, 0); 783 784 $data->sendstudentnotifications = false; 785 $assign->testable_apply_grade_to_user($data, $this->students[2]->id, 0); 786 787 // Now run cron and see that one message was sent. 788 $this->preventResetByRollback(); 789 $sink = $this->redirectMessages(); 790 cron_setup_user(); 791 $this->expectOutputRegex('/Done processing 2 assignment submissions/'); 792 assign::cron(); 793 794 $messages = $sink->get_messages(); 795 // The sent count should be 2, because the 3rd one was marked as do not send notifications. 796 $this->assertEquals(2, count($messages)); 797 $this->assertEquals(1, $messages[0]->notification); 798 $this->assertEquals($assign->get_instance()->name, $messages[0]->contexturlname); 799 } 800 801 public function test_is_graded() { 802 $this->setUser($this->editingteachers[0]); 803 $assign = $this->create_instance(); 804 805 // Simulate adding a grade. 806 $this->setUser($this->teachers[0]); 807 $data = new stdClass(); 808 $data->grade = '50.0'; 809 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 810 811 $this->assertEquals(true, $assign->testable_is_graded($this->students[0]->id)); 812 $this->assertEquals(false, $assign->testable_is_graded($this->students[1]->id)); 813 } 814 815 public function test_can_grade() { 816 global $DB; 817 818 $this->setUser($this->editingteachers[0]); 819 $assign = $this->create_instance(); 820 821 $this->setUser($this->students[0]); 822 $this->assertEquals(false, $assign->can_grade()); 823 $this->setUser($this->editingteachers[0]); 824 $this->assertEquals(true, $assign->can_grade()); 825 $this->setUser($this->teachers[0]); 826 $this->assertEquals(true, $assign->can_grade()); 827 828 // Test the viewgrades capability - without mod/assign:grade. 829 $this->setUser($this->students[0]); 830 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 831 assign_capability('mod/assign:viewgrades', CAP_ALLOW, $studentrole->id, $assign->get_context()->id); 832 $this->assertEquals(false, $assign->can_grade()); 833 } 834 835 public function test_can_view_submission() { 836 global $DB; 837 838 $this->create_extra_users(); 839 $this->setUser($this->editingteachers[0]); 840 $assign = $this->create_instance(); 841 842 $this->setUser($this->students[0]); 843 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id)); 844 $this->assertEquals(false, $assign->can_view_submission($this->students[1]->id)); 845 $this->assertEquals(false, $assign->can_view_submission($this->teachers[0]->id)); 846 $this->setUser($this->teachers[0]); 847 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id)); 848 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id)); 849 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id)); 850 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id)); 851 $this->setUser($this->editingteachers[0]); 852 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id)); 853 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id)); 854 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id)); 855 $this->assertEquals(true, $assign->can_view_submission($this->extrasuspendedstudents[0]->id)); 856 857 // Test the viewgrades capability - without mod/assign:grade. 858 $this->setUser($this->students[0]); 859 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 860 assign_capability('mod/assign:viewgrades', CAP_ALLOW, $studentrole->id, $assign->get_context()->id); 861 $this->assertEquals(true, $assign->can_view_submission($this->students[0]->id)); 862 $this->assertEquals(true, $assign->can_view_submission($this->students[1]->id)); 863 $this->assertEquals(true, $assign->can_view_submission($this->teachers[0]->id)); 864 $this->assertEquals(false, $assign->can_view_submission($this->extrasuspendedstudents[0]->id)); 865 } 866 867 868 public function test_update_submission() { 869 $this->create_extra_users(); 870 $this->setUser($this->editingteachers[0]); 871 $assign = $this->create_instance(); 872 873 $this->setUser($this->extrastudents[0]); 874 $now = time(); 875 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true); 876 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false); 877 878 $this->setUser($this->teachers[0]); 879 // Verify the gradebook update. 880 $gradinginfo = grade_get_grades($this->course->id, 881 'mod', 882 'assign', 883 $assign->get_instance()->id, 884 $this->extrastudents[0]->id); 885 886 $this->assertEquals($this->extrastudents[0]->id, 887 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified); 888 889 // Now verify group assignments. 890 $this->setUser($this->editingteachers[0]); 891 $assign = $this->create_instance(array('teamsubmission'=>1)); 892 893 $this->setUser($this->extrastudents[0]); 894 $now = time(); 895 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true); 896 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true); 897 898 // Check that at least 2 active members and 1 suspended member of the submission group had their submission updated. 899 900 $this->setUser($this->editingteachers[0]); 901 $gradinginfo = grade_get_grades($this->course->id, 902 'mod', 903 'assign', 904 $assign->get_instance()->id, 905 $this->extrastudents[0]->id); 906 907 $this->assertEquals($this->extrastudents[0]->id, 908 $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->usermodified); 909 910 $gradinginfo = grade_get_grades($this->course->id, 911 'mod', 912 'assign', 913 $assign->get_instance()->id, 914 $this->extrastudents[self::GROUP_COUNT]->id); 915 916 $this->assertEquals($this->extrastudents[self::GROUP_COUNT]->id, 917 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT]->id]->usermodified); 918 919 $gradinginfo = grade_get_grades($this->course->id, 920 'mod', 921 'assign', 922 $assign->get_instance()->id, 923 $this->extrasuspendedstudents[0]->id); 924 $this->assertEquals($this->extrasuspendedstudents[0]->id, 925 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[0]->id]->usermodified); 926 927 // Check the same with non-editing teacher and make sure submission is not updated for suspended user. 928 $this->setUser($this->editingteachers[0]); 929 $assign = $this->create_instance(array('teamsubmission'=>1)); 930 931 $this->setUser($this->extrastudents[1]); 932 $now = time(); 933 $submission = $assign->get_group_submission($this->extrastudents[1]->id, 0, true); 934 $assign->testable_update_submission($submission, $this->extrastudents[1]->id, true, true); 935 936 $this->setUser($this->teachers[0]); 937 $gradinginfo = grade_get_grades($this->course->id, 938 'mod', 939 'assign', 940 $assign->get_instance()->id, 941 $this->extrastudents[1]->id); 942 943 $this->assertEquals($this->extrastudents[1]->id, 944 $gradinginfo->items[0]->grades[$this->extrastudents[1]->id]->usermodified); 945 946 $gradinginfo = grade_get_grades($this->course->id, 947 'mod', 948 'assign', 949 $assign->get_instance()->id, 950 $this->extrastudents[self::GROUP_COUNT+1]->id); 951 952 $this->assertEquals($this->extrastudents[self::GROUP_COUNT+1]->id, 953 $gradinginfo->items[0]->grades[$this->extrastudents[self::GROUP_COUNT+1]->id]->usermodified); 954 955 $gradinginfo = grade_get_grades($this->course->id, 956 'mod', 957 'assign', 958 $assign->get_instance()->id, 959 $this->extrasuspendedstudents[1]->id); 960 $this->assertEquals($this->extrasuspendedstudents[1]->id, 961 $gradinginfo->items[0]->grades[$this->extrasuspendedstudents[1]->id]->usermodified); 962 963 // Now verify blind marking. 964 $this->setUser($this->editingteachers[0]); 965 $assign = $this->create_instance(array('blindmarking'=>1)); 966 967 $this->setUser($this->extrastudents[0]); 968 $now = time(); 969 $submission = $assign->get_user_submission($this->extrastudents[0]->id, true); 970 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, false); 971 972 $this->setUser($this->editingteachers[0]); 973 $gradinginfo = grade_get_grades($this->course->id, 974 'mod', 975 'assign', 976 $assign->get_instance()->id, 977 $this->extrastudents[0]->id); 978 979 $this->assertEquals(null, $gradinginfo->items[0]->grades[$this->extrastudents[0]->id]->datesubmitted); 980 } 981 982 public function test_group_submissions_submit_for_marking_requireallteammemberssubmit() { 983 global $PAGE; 984 985 $this->create_extra_users(); 986 // Now verify group assignments. 987 $this->setUser($this->editingteachers[0]); 988 $assign = $this->create_instance(array('teamsubmission'=>1, 989 'assignsubmission_onlinetext_enabled'=>1, 990 'submissiondrafts'=>1, 991 'requireallteammemberssubmit'=>1)); 992 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 993 994 // Add a submission. 995 $this->setUser($this->extrastudents[0]); 996 $data = new stdClass(); 997 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 998 'text'=>'Submission text', 999 'format'=>FORMAT_MOODLE); 1000 1001 $notices = array(); 1002 $assign->save_submission($data, $notices); 1003 1004 // Check we can see the submit button. 1005 $output = $assign->view_student_summary($this->extrastudents[0], true); 1006 $this->assertContains(get_string('submitassignment', 'assign'), $output); 1007 1008 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true); 1009 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1010 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true); 1011 1012 // Check that the student does not see "Submit" button. 1013 $output = $assign->view_student_summary($this->extrastudents[0], true); 1014 $this->assertNotContains(get_string('submitassignment', 'assign'), $output); 1015 1016 // Change to another user in the same group. 1017 $this->setUser($this->extrastudents[self::GROUP_COUNT]); 1018 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true); 1019 $this->assertContains(get_string('submitassignment', 'assign'), $output); 1020 1021 $submission = $assign->get_group_submission($this->extrastudents[self::GROUP_COUNT]->id, 0, true); 1022 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1023 $assign->testable_update_submission($submission, $this->extrastudents[self::GROUP_COUNT]->id, true, true); 1024 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true); 1025 $this->assertNotContains(get_string('submitassignment', 'assign'), $output); 1026 } 1027 1028 public function test_group_submissions_submit_for_marking() { 1029 global $PAGE; 1030 1031 $this->create_extra_users(); 1032 // Now verify group assignments. 1033 $this->setUser($this->editingteachers[0]); 1034 $time = time(); 1035 $assign = $this->create_instance(array('teamsubmission'=>1, 1036 'assignsubmission_onlinetext_enabled'=>1, 1037 'submissiondrafts'=>1, 1038 'requireallteammemberssubmit'=>0, 1039 'duedate' => $time - 2*24*60*60)); 1040 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1041 1042 $this->setUser($this->extrastudents[0]); 1043 // Add a submission. 1044 $data = new stdClass(); 1045 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1046 'text'=>'Submission text', 1047 'format'=>FORMAT_MOODLE); 1048 1049 $notices = array(); 1050 $assign->save_submission($data, $notices); 1051 1052 // Check we can see the submit button. 1053 $output = $assign->view_student_summary($this->extrastudents[0], true); 1054 $this->assertContains(get_string('submitassignment', 'assign'), $output); 1055 $this->assertContains(get_string('timeremaining', 'assign'), $output); 1056 $difftime = time() - $time; 1057 $this->assertContains(get_string('overdue', 'assign', format_time(2*24*60*60 + $difftime)), $output); 1058 1059 $submission = $assign->get_group_submission($this->extrastudents[0]->id, 0, true); 1060 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1061 $assign->testable_update_submission($submission, $this->extrastudents[0]->id, true, true); 1062 1063 // Check that the student does not see "Submit" button. 1064 $output = $assign->view_student_summary($this->extrastudents[0], true); 1065 $this->assertNotContains(get_string('submitassignment', 'assign'), $output); 1066 1067 // Change to another user in the same group. 1068 $this->setUser($this->extrastudents[self::GROUP_COUNT]); 1069 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true); 1070 $this->assertNotContains(get_string('submitassignment', 'assign'), $output); 1071 1072 // Check that time remaining is not overdue. 1073 $this->assertContains(get_string('timeremaining', 'assign'), $output); 1074 $difftime = time() - $time; 1075 $this->assertContains(get_string('submittedlate', 'assign', format_time(2*24*60*60 + $difftime)), $output); 1076 1077 $submission = $assign->get_group_submission($this->extrastudents[self::GROUP_COUNT]->id, 0, true); 1078 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1079 $assign->testable_update_submission($submission, $this->extrastudents[self::GROUP_COUNT]->id, true, true); 1080 $output = $assign->view_student_summary($this->extrastudents[self::GROUP_COUNT], true); 1081 $this->assertNotContains(get_string('submitassignment', 'assign'), $output); 1082 } 1083 1084 public function test_submissions_open() { 1085 $this->setUser($this->editingteachers[0]); 1086 1087 $now = time(); 1088 $tomorrow = $now + 24*60*60; 1089 $oneweek = $now + 7*24*60*60; 1090 $yesterday = $now - 24*60*60; 1091 1092 $assign = $this->create_instance(); 1093 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1094 1095 $assign = $this->create_instance(array('duedate'=>$tomorrow)); 1096 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1097 1098 $assign = $this->create_instance(array('duedate'=>$yesterday)); 1099 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1100 1101 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$tomorrow)); 1102 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1103 1104 $assign = $this->create_instance(array('duedate'=>$yesterday, 'cutoffdate'=>$yesterday)); 1105 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id)); 1106 1107 $assign->testable_save_user_extension($this->students[0]->id, $tomorrow); 1108 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1109 1110 $assign = $this->create_instance(array('submissiondrafts'=>1)); 1111 $this->assertEquals(true, $assign->testable_submissions_open($this->students[0]->id)); 1112 1113 $this->setUser($this->students[0]); 1114 $now = time(); 1115 $submission = $assign->get_user_submission($this->students[0]->id, true); 1116 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1117 $assign->testable_update_submission($submission, $this->students[0]->id, true, false); 1118 $this->setUser($this->editingteachers[0]); 1119 $this->assertEquals(false, $assign->testable_submissions_open($this->students[0]->id)); 1120 } 1121 1122 public function test_get_graders() { 1123 $this->create_extra_users(); 1124 $this->setUser($this->editingteachers[0]); 1125 1126 // Create an assignment with no groups. 1127 $assign = $this->create_instance(); 1128 $this->assertCount(self::DEFAULT_TEACHER_COUNT + 1129 self::DEFAULT_EDITING_TEACHER_COUNT + 1130 self::EXTRA_TEACHER_COUNT + 1131 self::EXTRA_EDITING_TEACHER_COUNT, 1132 $assign->testable_get_graders($this->students[0]->id)); 1133 1134 // Force create an assignment with SEPARATEGROUPS. 1135 $data = new stdClass(); 1136 $data->courseid = $this->course->id; 1137 $data->name = 'Grouping'; 1138 $groupingid = groups_create_grouping($data); 1139 groups_assign_grouping($groupingid, $this->groups[0]->id); 1140 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS)); 1141 1142 $this->setUser($this->students[1]); 1143 $this->assertCount(4, $assign->testable_get_graders($this->students[0]->id)); 1144 // Note the second student is in a group that is not in the grouping. 1145 // This means that we get all graders that are not in a group in the grouping. 1146 $this->assertCount(10, $assign->testable_get_graders($this->students[1]->id)); 1147 } 1148 1149 public function test_get_notified_users() { 1150 global $CFG, $DB; 1151 1152 $capability = 'mod/assign:receivegradernotifications'; 1153 $coursecontext = context_course::instance($this->course->id); 1154 $role = $DB->get_record('role', array('shortname' => 'teacher')); 1155 1156 $this->create_extra_users(); 1157 $this->setUser($this->editingteachers[0]); 1158 1159 // Create an assignment with no groups. 1160 $assign = $this->create_instance(); 1161 1162 $this->assertCount(self::DEFAULT_TEACHER_COUNT + 1163 self::DEFAULT_EDITING_TEACHER_COUNT + 1164 self::EXTRA_TEACHER_COUNT + 1165 self::EXTRA_EDITING_TEACHER_COUNT, 1166 $assign->testable_get_notifiable_users($this->students[0]->id)); 1167 1168 // Change nonediting teachers role to not receive grader notifications. 1169 assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext); 1170 1171 $this->assertCount(self::DEFAULT_EDITING_TEACHER_COUNT + 1172 self::EXTRA_EDITING_TEACHER_COUNT, 1173 $assign->testable_get_notifiable_users($this->students[0]->id)); 1174 1175 // Reset nonediting teachers role to default. 1176 unassign_capability($capability, $role->id, $coursecontext); 1177 1178 // Force create an assignment with SEPARATEGROUPS. 1179 $data = new stdClass(); 1180 $data->courseid = $this->course->id; 1181 $data->name = 'Grouping'; 1182 $groupingid = groups_create_grouping($data); 1183 groups_assign_grouping($groupingid, $this->groups[0]->id); 1184 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS)); 1185 1186 $this->setUser($this->students[1]); 1187 $this->assertCount(4, $assign->testable_get_notifiable_users($this->students[0]->id)); 1188 // Note the second student is in a group that is not in the grouping. 1189 // This means that we get all graders that are not in a group in the grouping. 1190 $this->assertCount(10, $assign->testable_get_notifiable_users($this->students[1]->id)); 1191 1192 // Change nonediting teachers role to not receive grader notifications. 1193 assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext); 1194 1195 $this->assertCount(2, $assign->testable_get_notifiable_users($this->students[0]->id)); 1196 // Note the second student is in a group that is not in the grouping. 1197 // This means that we get all graders that are not in a group in the grouping. 1198 $this->assertCount(5, $assign->testable_get_notifiable_users($this->students[1]->id)); 1199 } 1200 1201 public function test_group_members_only() { 1202 global $CFG; 1203 1204 $this->setAdminUser(); 1205 $this->create_extra_users(); 1206 $CFG->enableavailability = true; 1207 $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $this->course->id)); 1208 groups_assign_grouping($grouping->id, $this->groups[0]->id); 1209 1210 // Force create an assignment with SEPARATEGROUPS. 1211 $instance = $this->getDataGenerator()->create_module('assign', array('course'=>$this->course->id), 1212 array('availability' => json_encode(\core_availability\tree::get_root_json(array( 1213 \availability_grouping\condition::get_json()))), 1214 'groupingid' => $grouping->id)); 1215 1216 $cm = get_coursemodule_from_instance('assign', $instance->id); 1217 $context = context_module::instance($cm->id); 1218 $assign = new testable_assign($context, $cm, $this->course); 1219 1220 $this->setUser($this->teachers[0]); 1221 get_fast_modinfo($this->course, 0, true); 1222 $this->assertCount(5, $assign->list_participants(0, true)); 1223 1224 } 1225 1226 public function test_get_uniqueid_for_user() { 1227 $this->setUser($this->editingteachers[0]); 1228 $assign = $this->create_instance(); 1229 1230 foreach ($this->students as $student) { 1231 $uniqueid = $assign->get_uniqueid_for_user($student->id); 1232 $this->assertEquals($student->id, $assign->get_user_id_for_uniqueid($uniqueid)); 1233 } 1234 } 1235 1236 public function test_show_student_summary() { 1237 global $CFG, $PAGE; 1238 1239 $this->setUser($this->editingteachers[0]); 1240 $assign = $this->create_instance(); 1241 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1242 1243 // No feedback should be available because this student has not been graded. 1244 $this->setUser($this->students[0]); 1245 $output = $assign->view_student_summary($this->students[0], true); 1246 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if there is no grade'); 1247 // Simulate adding a grade. 1248 $this->setUser($this->teachers[0]); 1249 $data = new stdClass(); 1250 $data->grade = '50.0'; 1251 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1252 1253 // Now we should see the feedback. 1254 $this->setUser($this->students[0]); 1255 $output = $assign->view_student_summary($this->students[0], true); 1256 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback if there is a grade'); 1257 1258 // Now hide the grade in gradebook. 1259 $this->setUser($this->teachers[0]); 1260 require_once($CFG->libdir.'/gradelib.php'); 1261 $gradeitem = new grade_item(array( 1262 'itemtype' => 'mod', 1263 'itemmodule' => 'assign', 1264 'iteminstance' => $assign->get_instance()->id, 1265 'courseid' => $this->course->id)); 1266 1267 $gradeitem->set_hidden(1, false); 1268 1269 // No feedback should be available because the grade is hidden. 1270 $this->setUser($this->students[0]); 1271 $output = $assign->view_student_summary($this->students[0], true); 1272 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook'); 1273 1274 // Do the same but add feedback. 1275 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1)); 1276 1277 $this->setUser($this->teachers[0]); 1278 $grade = $assign->get_user_grade($this->students[0]->id, true); 1279 $data = new stdClass(); 1280 $data->assignfeedbackcomments_editor = array('text'=>'Tomato sauce', 1281 'format'=>FORMAT_MOODLE); 1282 $plugin = $assign->get_feedback_plugin_by_type('comments'); 1283 $plugin->save($grade, $data); 1284 1285 // Should have feedback but no grade. 1286 $this->setUser($this->students[0]); 1287 $output = $assign->view_student_summary($this->students[0], true); 1288 $this->assertNotEquals(false, strpos($output, 'Feedback'), 'Show feedback even if there is no grade'); 1289 $this->assertEquals(false, strpos($output, 'Grade'), 'Do not show grade when there is no grade.'); 1290 $this->assertEquals(false, strpos($output, 'Graded on'), 'Do not show graded date when there is no grade.'); 1291 1292 // Now hide the grade in gradebook. 1293 $this->setUser($this->teachers[0]); 1294 $gradeitem = new grade_item(array( 1295 'itemtype' => 'mod', 1296 'itemmodule' => 'assign', 1297 'iteminstance' => $assign->get_instance()->id, 1298 'courseid' => $this->course->id)); 1299 1300 $gradeitem->set_hidden(1, false); 1301 1302 // No feedback should be available because the grade is hidden. 1303 $this->setUser($this->students[0]); 1304 $output = $assign->view_student_summary($this->students[0], true); 1305 $this->assertEquals(false, strpos($output, 'Feedback'), 'Do not show feedback if the grade is hidden in the gradebook'); 1306 } 1307 1308 public function test_attempt_reopen_method_manual() { 1309 global $PAGE; 1310 1311 $this->setUser($this->editingteachers[0]); 1312 $assign = $this->create_instance(array('attemptreopenmethod'=>ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL, 1313 'maxattempts'=>3, 1314 'submissiondrafts'=>1, 1315 'assignsubmission_onlinetext_enabled'=>1)); 1316 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1317 1318 // Student should be able to see an add submission button. 1319 $this->setUser($this->students[0]); 1320 $output = $assign->view_student_summary($this->students[0], true); 1321 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign'))); 1322 1323 // Add a submission. 1324 $now = time(); 1325 $submission = $assign->get_user_submission($this->students[0]->id, true); 1326 $data = new stdClass(); 1327 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1328 'text'=>'Submission text', 1329 'format'=>FORMAT_MOODLE); 1330 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 1331 $plugin->save($submission, $data); 1332 1333 // And now submit it for marking. 1334 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 1335 $assign->testable_update_submission($submission, $this->students[0]->id, true, false); 1336 1337 // Verify the student cannot make changes to the submission. 1338 $output = $assign->view_student_summary($this->students[0], true); 1339 $this->assertEquals(false, strpos($output, get_string('addsubmission', 'assign'))); 1340 1341 // Mark the submission. 1342 $this->setUser($this->teachers[0]); 1343 $data = new stdClass(); 1344 $data->grade = '50.0'; 1345 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1346 1347 // Check the student can see the grade. 1348 $this->setUser($this->students[0]); 1349 $output = $assign->view_student_summary($this->students[0], true); 1350 $this->assertNotEquals(false, strpos($output, '50.0')); 1351 1352 // Allow the student another attempt. 1353 $this->teachers[0]->ignoresesskey = true; 1354 $this->setUser($this->teachers[0]); 1355 $result = $assign->testable_process_add_attempt($this->students[0]->id); 1356 $this->assertEquals(true, $result); 1357 1358 // Check that the previous attempt is now in the submission history table. 1359 $this->setUser($this->students[0]); 1360 $output = $assign->view_student_summary($this->students[0], true); 1361 // Need a better check. 1362 $this->assertNotEquals(false, strpos($output, 'Submission text'), 'Contains: Submission text'); 1363 1364 // Check that the student now has a button for Add a new attempt". 1365 $this->assertNotEquals(false, strpos($output, get_string('addnewattempt', 'assign'))); 1366 // Check that the student now does not have a button for Submit. 1367 $this->assertEquals(false, strpos($output, get_string('submitassignment', 'assign'))); 1368 1369 // Check that the student now has a submission history. 1370 $this->assertNotEquals(false, strpos($output, get_string('attempthistory', 'assign'))); 1371 1372 $this->setUser($this->teachers[0]); 1373 // Check that the grading table loads correctly and contains this user. 1374 // This is also testing that we do not get duplicate rows in the grading table. 1375 $gradingtable = new assign_grading_table($assign, 100, '', 0, true); 1376 $output = $assign->get_renderer()->render($gradingtable); 1377 $this->assertEquals(true, strpos($output, $this->students[0]->lastname)); 1378 1379 // Should be 1 not 2. 1380 $this->assertEquals(1, $assign->count_submissions()); 1381 $this->assertEquals(1, $assign->count_submissions_with_status('reopened')); 1382 $this->assertEquals(0, $assign->count_submissions_need_grading()); 1383 $this->assertEquals(1, $assign->count_grades()); 1384 1385 // Change max attempts to unlimited. 1386 $formdata = clone($assign->get_instance()); 1387 $formdata->maxattempts = ASSIGN_UNLIMITED_ATTEMPTS; 1388 $formdata->instance = $formdata->id; 1389 $assign->update_instance($formdata); 1390 1391 // Mark the submission again. 1392 $data = new stdClass(); 1393 $data->grade = '60.0'; 1394 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 1); 1395 1396 // Check the grade exists. 1397 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id); 1398 $this->assertEquals(60, (int)$grades[$this->students[0]->id]->rawgrade); 1399 1400 // Check we can reopen still. 1401 $result = $assign->testable_process_add_attempt($this->students[0]->id); 1402 $this->assertEquals(true, $result); 1403 1404 // Should no longer have a grade because there is no grade for the latest attempt. 1405 $grades = $assign->get_user_grades_for_gradebook($this->students[0]->id); 1406 $this->assertEmpty($grades); 1407 1408 } 1409 1410 public function test_markingworkflow() { 1411 global $PAGE; 1412 1413 $this->setUser($this->editingteachers[0]); 1414 $assign = $this->create_instance(array('markingworkflow'=>1)); 1415 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1416 1417 // Mark the submission and set to notmarked. 1418 $this->setUser($this->teachers[0]); 1419 $data = new stdClass(); 1420 $data->grade = '50.0'; 1421 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED; 1422 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1423 1424 // Check the student can't see the grade. 1425 $this->setUser($this->students[0]); 1426 $output = $assign->view_student_summary($this->students[0], true); 1427 $this->assertEquals(false, strpos($output, '50.0')); 1428 1429 // Mark the submission and set to inmarking. 1430 $this->setUser($this->teachers[0]); 1431 $data = new stdClass(); 1432 $data->grade = '50.0'; 1433 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INMARKING; 1434 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1435 1436 // Check the student can't see the grade. 1437 $this->setUser($this->students[0]); 1438 $output = $assign->view_student_summary($this->students[0], true); 1439 $this->assertEquals(false, strpos($output, '50.0')); 1440 1441 // Mark the submission and set to readyforreview. 1442 $this->setUser($this->teachers[0]); 1443 $data = new stdClass(); 1444 $data->grade = '50.0'; 1445 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW; 1446 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1447 1448 // Check the student can't see the grade. 1449 $this->setUser($this->students[0]); 1450 $output = $assign->view_student_summary($this->students[0], true); 1451 $this->assertEquals(false, strpos($output, '50.0')); 1452 1453 // Mark the submission and set to inreview. 1454 $this->setUser($this->teachers[0]); 1455 $data = new stdClass(); 1456 $data->grade = '50.0'; 1457 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW; 1458 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1459 1460 // Check the student can't see the grade. 1461 $this->setUser($this->students[0]); 1462 $output = $assign->view_student_summary($this->students[0], true); 1463 $this->assertEquals(false, strpos($output, '50.0')); 1464 1465 // Mark the submission and set to readyforrelease. 1466 $this->setUser($this->teachers[0]); 1467 $data = new stdClass(); 1468 $data->grade = '50.0'; 1469 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE; 1470 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1471 1472 // Check the student can't see the grade. 1473 $this->setUser($this->students[0]); 1474 $output = $assign->view_student_summary($this->students[0], true); 1475 $this->assertEquals(false, strpos($output, '50.0')); 1476 1477 // Mark the submission and set to released. 1478 $this->setUser($this->teachers[0]); 1479 $data = new stdClass(); 1480 $data->grade = '50.0'; 1481 $data->workflowstate = ASSIGN_MARKING_WORKFLOW_STATE_RELEASED; 1482 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1483 1484 // Check the student can see the grade. 1485 $this->setUser($this->students[0]); 1486 $output = $assign->view_student_summary($this->students[0], true); 1487 $this->assertNotEquals(false, strpos($output, '50.0')); 1488 } 1489 1490 public function test_markerallocation() { 1491 global $PAGE; 1492 1493 $this->setUser($this->editingteachers[0]); 1494 $assign = $this->create_instance(array('markingworkflow'=>1, 'markingallocation'=>1)); 1495 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1496 1497 // Allocate marker to submission. 1498 $data = new stdClass(); 1499 $data->allocatedmarker = $this->teachers[0]->id; 1500 $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0); 1501 1502 // Check the allocated marker can view the submission. 1503 $this->setUser($this->teachers[0]); 1504 $gradingtable = new assign_grading_table($assign, 100, '', 0, true); 1505 $output = $assign->get_renderer()->render($gradingtable); 1506 $this->assertEquals(true, strpos($output, $this->students[0]->lastname)); 1507 1508 // Check that other teachers can't view this submission. 1509 $this->setUser($this->teachers[1]); 1510 $gradingtable = new assign_grading_table($assign, 100, '', 0, true); 1511 $output = $assign->get_renderer()->render($gradingtable); 1512 $this->assertNotEquals(true, strpos($output, $this->students[0]->lastname)); 1513 } 1514 1515 1516 1517 public function test_teacher_submit_for_student() { 1518 global $PAGE; 1519 1520 $this->preventResetByRollback(); 1521 $sink = $this->redirectMessages(); 1522 1523 $this->setUser($this->editingteachers[0]); 1524 1525 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1)); 1526 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1527 1528 $this->setUser($this->students[0]); 1529 // Simulate a submission. 1530 $data = new stdClass(); 1531 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1532 'text'=>'Student submission text', 1533 'format'=>FORMAT_MOODLE); 1534 1535 $notices = array(); 1536 $assign->save_submission($data, $notices); 1537 1538 // Check that the submission text was saved. 1539 $output = $assign->view_student_summary($this->students[0], true); 1540 $this->assertContains('Student submission text', $output, 'Contains student submission text'); 1541 1542 // Check that a teacher teacher with the extra capability can edit a students submission. 1543 $this->setUser($this->teachers[0]); 1544 $data = new stdClass(); 1545 $data->userid = $this->students[0]->id; 1546 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1547 'text'=>'Teacher edited submission text', 1548 'format'=>FORMAT_MOODLE); 1549 1550 // Add the required capability. 1551 $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description'); 1552 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id); 1553 role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id); 1554 accesslib_clear_all_caches_for_unit_testing(); 1555 1556 // Try to save the submission. 1557 $notices = array(); 1558 $assign->save_submission($data, $notices); 1559 1560 // Check that the teacher can submit the students work. 1561 $data = new stdClass(); 1562 $data->userid = $this->students[0]->id; 1563 $notices = array(); 1564 $assign->submit_for_grading($data, $notices); 1565 1566 // Revert to draft so the student can edit it. 1567 $assign->revert_to_draft($this->students[0]->id); 1568 1569 $this->setUser($this->students[0]); 1570 1571 // Check that the submission text was saved. 1572 $output = $assign->view_student_summary($this->students[0], true); 1573 $this->assertContains('Teacher edited submission text', $output, 'Contains student submission text'); 1574 1575 // Check that the student can submit their work. 1576 $data = new stdClass(); 1577 $assign->submit_for_grading($data, $notices); 1578 1579 $output = $assign->view_student_summary($this->students[0], true); 1580 $this->assertNotContains(get_string('addsubmission', 'assign'), $output); 1581 1582 // Set to a default editing teacher who should not be able to edit this submission. 1583 $this->setUser($this->editingteachers[1]); 1584 1585 // Revert to draft so the submission is editable. 1586 $assign->revert_to_draft($this->students[0]->id); 1587 1588 $data = new stdClass(); 1589 $data->userid = $this->students[0]->id; 1590 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1591 'text'=>'Teacher 2 edited submission text', 1592 'format'=>FORMAT_MOODLE); 1593 1594 $notices = array(); 1595 $this->setExpectedException('moodle_exception'); 1596 $assign->save_submission($data, $notices); 1597 1598 $sink->close(); 1599 } 1600 1601 public function test_disable_submit_after_cutoff_date() { 1602 global $PAGE; 1603 1604 $this->setUser($this->editingteachers[0]); 1605 $now = time(); 1606 $tomorrow = $now + 24*60*60; 1607 $lastweek = $now - 7*24*60*60; 1608 $yesterday = $now - 24*60*60; 1609 1610 $assign = $this->create_instance(array('duedate'=>$yesterday, 1611 'cutoffdate'=>$tomorrow, 1612 'assignsubmission_onlinetext_enabled'=>1)); 1613 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1614 1615 // Student should be able to see an add submission button. 1616 $this->setUser($this->students[0]); 1617 $output = $assign->view_student_summary($this->students[0], true); 1618 $this->assertNotEquals(false, strpos($output, get_string('addsubmission', 'assign'))); 1619 1620 // Add a submission but don't submit now. 1621 $submission = $assign->get_user_submission($this->students[0]->id, true); 1622 $data = new stdClass(); 1623 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1624 'text'=>'Submission text', 1625 'format'=>FORMAT_MOODLE); 1626 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 1627 $plugin->save($submission, $data); 1628 1629 // Create another instance with cut-off and due-date already passed. 1630 $this->setUser($this->editingteachers[0]); 1631 $now = time(); 1632 $assign = $this->create_instance(array('duedate'=>$lastweek, 1633 'cutoffdate'=>$yesterday, 1634 'assignsubmission_onlinetext_enabled'=>1)); 1635 1636 $this->setUser($this->students[0]); 1637 $output = $assign->view_student_summary($this->students[0], true); 1638 $this->assertNotContains($output, get_string('editsubmission', 'assign'), 1639 'Should not be able to edit after cutoff date.'); 1640 $this->assertNotContains($output, get_string('submitassignment', 'assign'), 1641 'Should not be able to submit after cutoff date.'); 1642 } 1643 /** 1644 * Testing for submission comment plugin settings 1645 */ 1646 public function test_submission_comment_plugin_settings() { 1647 global $CFG; 1648 1649 $commentconfig = false; 1650 if (!empty($CFG->usecomments)) { 1651 $commentconfig = $CFG->usecomments; 1652 } 1653 1654 $CFG->usecomments = true; 1655 $assign = $this->create_instance(); 1656 $plugin = $assign->get_submission_plugin_by_type('comments'); 1657 $this->assertEquals(1, $plugin->is_enabled('enabled')); 1658 1659 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 0)); 1660 $plugin = $assign->get_submission_plugin_by_type('comments'); 1661 $this->assertEquals(1, $plugin->is_enabled('enabled')); 1662 1663 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 1)); 1664 $plugin = $assign->get_submission_plugin_by_type('comments'); 1665 $this->assertEquals(1, $plugin->is_enabled('enabled')); 1666 1667 $CFG->usecomments = false; 1668 $assign = $this->create_instance(); 1669 $plugin = $assign->get_submission_plugin_by_type('comments'); 1670 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1671 1672 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 0)); 1673 $plugin = $assign->get_submission_plugin_by_type('comments'); 1674 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1675 1676 $assign = $this->create_instance(array('assignsubmission_comments_enabled' => 1)); 1677 $plugin = $assign->get_submission_plugin_by_type('comments'); 1678 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1679 1680 $CFG->usecomments = $commentconfig; 1681 } 1682 1683 /** 1684 * Testing for comment inline settings 1685 */ 1686 public function test_feedback_comment_commentinline() { 1687 global $CFG; 1688 1689 $sourcetext = "Hello! 1690 1691 I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. 1692 1693 URL outside a tag: https://moodle.org/logo/logo-240x60.gif 1694 Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif 1695 1696 External link 1:<img src='https://moodle.org/logo/logo-240x60.gif' alt='Moodle'/> 1697 External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\"/> 1698 Internal link 1:<img src='@@PLUGINFILE@@/logo-240x60.gif' alt='Moodle'/> 1699 Internal link 2:<img alt=\"Moodle\" src=\"@@PLUGINFILE@@logo-240x60.gif\"/> 1700 Anchor link 1:<a href=\"@@PLUGINFILE@@logo-240x60.gif\" alt=\"bananas\">Link text</a> 1701 Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a> 1702 "; 1703 1704 // Note the internal images have been stripped and the html is purified (quotes fixed in this case). 1705 $filteredtext = "Hello! 1706 1707 I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. 1708 1709 URL outside a tag: https://moodle.org/logo/logo-240x60.gif 1710 Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif 1711 1712 External link 1:<img src=\"https://moodle.org/logo/logo-240x60.gif\" alt=\"Moodle\" /> 1713 External link 2:<img alt=\"Moodle\" src=\"https://moodle.org/logo/logo-240x60.gif\" /> 1714 Internal link 1: 1715 Internal link 2: 1716 Anchor link 1:Link text 1717 Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a> 1718 "; 1719 1720 $this->setUser($this->editingteachers[0]); 1721 $params = array('assignsubmission_onlinetext_enabled' => 1, 1722 'assignfeedback_comments_enabled' => 1, 1723 'assignfeedback_comments_commentinline' => 1); 1724 $assign = $this->create_instance($params); 1725 1726 $this->setUser($this->students[0]); 1727 // Add a submission but don't submit now. 1728 $submission = $assign->get_user_submission($this->students[0]->id, true); 1729 $data = new stdClass(); 1730 1731 // Test the internal link is stripped, but the external one is not. 1732 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 1733 'text'=>$sourcetext, 1734 'format'=>FORMAT_MOODLE); 1735 1736 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 1737 $plugin->save($submission, $data); 1738 1739 $this->setUser($this->editingteachers[0]); 1740 1741 $data = new stdClass(); 1742 require_once($CFG->dirroot . '/mod/assign/gradeform.php'); 1743 $pagination = array('userid'=>$this->students[0]->id, 1744 'rownum'=>0, 1745 'last'=>true, 1746 'useridlistid'=>time(), 1747 'attemptnumber'=>0); 1748 $formparams = array($assign, $data, $pagination); 1749 $mform = new mod_assign_grade_form(null, $formparams); 1750 1751 $this->assertEquals($filteredtext, $data->assignfeedbackcomments_editor['text']); 1752 } 1753 1754 /** 1755 * Testing for feedback comment plugin settings 1756 */ 1757 public function test_feedback_plugin_settings() { 1758 1759 $assign = $this->create_instance(); 1760 $plugin = $assign->get_feedback_plugin_by_type('comments'); 1761 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1762 1763 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 0)); 1764 $plugin = $assign->get_feedback_plugin_by_type('comments'); 1765 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1766 1767 $assign = $this->create_instance(array('assignfeedback_comments_enabled' => 1)); 1768 $plugin = $assign->get_feedback_plugin_by_type('comments'); 1769 $this->assertEquals(1, $plugin->is_enabled('enabled')); 1770 } 1771 1772 /** 1773 * Testing if gradebook feedback plugin is enabled. 1774 */ 1775 public function test_is_gradebook_feedback_enabled() { 1776 $adminconfig = get_config('assign'); 1777 $gradebookplugin = $adminconfig->feedback_plugin_for_gradebook; 1778 1779 // Create assignment with gradebook feedback enabled and grade = 0. 1780 $assign = $this->create_instance(array($gradebookplugin . '_enabled' => 1, 'grades' => 0)); 1781 1782 // Get gradebook feedback plugin. 1783 $gradebookplugintype = str_replace('assignfeedback_', '', $gradebookplugin); 1784 $plugin = $assign->get_feedback_plugin_by_type($gradebookplugintype); 1785 $this->assertEquals(1, $plugin->is_enabled('enabled')); 1786 $this->assertEquals(1, $assign->is_gradebook_feedback_enabled()); 1787 1788 // Create assignment with gradebook feedback disabled and grade = 0. 1789 $assign = $this->create_instance(array($gradebookplugin . '_enabled' => 0, 'grades' => 0)); 1790 $plugin = $assign->get_feedback_plugin_by_type($gradebookplugintype); 1791 $this->assertEquals(0, $plugin->is_enabled('enabled')); 1792 } 1793 1794 /** 1795 * Testing can_edit_submission 1796 */ 1797 public function test_can_edit_submission() { 1798 global $PAGE, $DB; 1799 $this->create_extra_users(); 1800 1801 $this->setAdminUser(); 1802 // Create assignment (onlinetext). 1803 $assign = $this->create_instance(array('assignsubmission_onlinetext_enabled'=>1, 'submissiondrafts'=>1)); 1804 $PAGE->set_url(new moodle_url('/mod/assign/view.php', array('id' => $assign->get_course_module()->id))); 1805 1806 // Check student can edit their own submission. 1807 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->students[0]->id)); 1808 // Check student cannot edit others submission. 1809 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->students[1]->id)); 1810 1811 // Check teacher cannot (by default) edit a students submission. 1812 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id)); 1813 1814 // Add the required capability to edit a student submission. 1815 $roleid = create_role('Dummy role', 'dummyrole', 'dummy role description'); 1816 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id); 1817 role_assign($roleid, $this->teachers[0]->id, $assign->get_context()->id); 1818 accesslib_clear_all_caches_for_unit_testing(); 1819 // Retest - should now have access. 1820 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->teachers[0]->id)); 1821 1822 // Force create an assignment with SEPARATEGROUPS. 1823 $data = new stdClass(); 1824 $data->courseid = $this->course->id; 1825 $data->name = 'Grouping'; 1826 $groupingid = groups_create_grouping($data); 1827 groups_assign_grouping($groupingid, $this->groups[0]->id); 1828 groups_assign_grouping($groupingid, $this->groups[1]->id); 1829 $assign = $this->create_instance(array('groupingid' => $groupingid, 'groupmode' => SEPARATEGROUPS)); 1830 1831 // Add the capability to the new assignment for extra students 0 and 1. 1832 assign_capability('mod/assign:editothersubmission', CAP_ALLOW, $roleid, $assign->get_context()->id); 1833 role_assign($roleid, $this->extrastudents[0]->id, $assign->get_context()->id); 1834 role_assign($roleid, $this->extrastudents[1]->id, $assign->get_context()->id); 1835 accesslib_clear_all_caches_for_unit_testing(); 1836 1837 // Verify the extra student does not have the capability to edit a submission not in their group. 1838 $this->assertFalse($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[1]->id)); 1839 // Verify the extra student does have the capability to edit a submission in their group. 1840 $this->assertTrue($assign->can_edit_submission($this->students[0]->id, $this->extrastudents[0]->id)); 1841 1842 } 1843 1844 /** 1845 * Test if the view blind details capability works 1846 */ 1847 public function test_can_view_blind_details() { 1848 global $PAGE, $DB; 1849 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1850 $managerrole = $DB->get_record('role', array('shortname' => 'manager')); 1851 1852 $student = $this->students[0];// Get a student user. 1853 // Create a teacher. Shouldn't be able to view blind marking ID. 1854 $teacher = $this->getDataGenerator()->create_user(); 1855 1856 $this->getDataGenerator()->enrol_user($teacher->id, 1857 $this->course->id, 1858 $teacherrole->id); 1859 1860 // Create a manager.. Should be able to view blind marking ID. 1861 $manager = $this->getDataGenerator()->create_user(); 1862 $this->getDataGenerator()->enrol_user($manager->id, 1863 $this->course->id, 1864 $managerrole->id); 1865 1866 // Generate blind marking assignment. 1867 $assign = $this->create_instance(array('blindmarking' => 1)); 1868 $this->assertEquals(true, $assign->is_blind_marking()); 1869 1870 // Test student names are hidden to teacher. 1871 $this->setUser($teacher); 1872 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 1873 $output = $assign->get_renderer()->render($gradingtable); 1874 $this->assertEquals(true, strpos($output, get_string('hiddenuser', 'assign'))); // "Participant" is somewhere on the page. 1875 $this->assertEquals(false, strpos($output, fullname($student))); // Students full name doesn't appear. 1876 1877 // Test student names are visible to manager. 1878 $this->setUser($manager); 1879 $gradingtable = new assign_grading_table($assign, 1, '', 0, true); 1880 $output = $assign->get_renderer()->render($gradingtable); 1881 $this->assertEquals(false, strpos($output, get_string('hiddenuser', 'assign'))); 1882 $this->assertEquals(true, strpos($output, fullname($student))); //students full name doesn't appear. 1883 } 1884 } 1885
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |