[ Index ] |
PHP Cross Reference of Unnamed Project |
[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 defined('MOODLE_INTERNAL') || die(); 18 19 global $CFG; 20 21 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 22 23 /** 24 * External mod assign functions unit tests 25 * 26 * @package mod_assign 27 * @category external 28 * @copyright 2012 Paul Charsley 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 class mod_assign_external_testcase extends externallib_advanced_testcase { 32 33 /** 34 * Tests set up 35 */ 36 protected function setUp() { 37 global $CFG; 38 require_once($CFG->dirroot . '/mod/assign/externallib.php'); 39 } 40 41 /** 42 * Test get_grades 43 */ 44 public function test_get_grades() { 45 global $DB, $USER; 46 47 $this->resetAfterTest(true); 48 // Create a course and assignment. 49 $coursedata['idnumber'] = 'idnumbercourse'; 50 $coursedata['fullname'] = 'Lightwork Course'; 51 $coursedata['summary'] = 'Lightwork Course description'; 52 $coursedata['summaryformat'] = FORMAT_MOODLE; 53 $course = self::getDataGenerator()->create_course($coursedata); 54 55 $assigndata['course'] = $course->id; 56 $assigndata['name'] = 'lightwork assignment'; 57 58 $assign = self::getDataGenerator()->create_module('assign', $assigndata); 59 60 // Create a manual enrolment record. 61 $manualenroldata['enrol'] = 'manual'; 62 $manualenroldata['status'] = 0; 63 $manualenroldata['courseid'] = $course->id; 64 $enrolid = $DB->insert_record('enrol', $manualenroldata); 65 66 // Create a teacher and give them capabilities. 67 $context = context_course::instance($course->id); 68 $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); 69 $context = context_module::instance($assign->cmid); 70 $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); 71 72 // Create the teacher's enrolment record. 73 $userenrolmentdata['status'] = 0; 74 $userenrolmentdata['enrolid'] = $enrolid; 75 $userenrolmentdata['userid'] = $USER->id; 76 $DB->insert_record('user_enrolments', $userenrolmentdata); 77 78 // Create a student and give them 2 grades (for 2 attempts). 79 $student = self::getDataGenerator()->create_user(); 80 81 $submission = new stdClass(); 82 $submission->assignment = $assign->id; 83 $submission->userid = $student->id; 84 $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; 85 $submission->latest = 0; 86 $submission->attemptnumber = 0; 87 $submission->groupid = 0; 88 $submission->timecreated = time(); 89 $submission->timemodified = time(); 90 $DB->insert_record('assign_submission', $submission); 91 92 $grade = new stdClass(); 93 $grade->assignment = $assign->id; 94 $grade->userid = $student->id; 95 $grade->timecreated = time(); 96 $grade->timemodified = $grade->timecreated; 97 $grade->grader = $USER->id; 98 $grade->grade = 50; 99 $grade->attemptnumber = 0; 100 $DB->insert_record('assign_grades', $grade); 101 102 $submission = new stdClass(); 103 $submission->assignment = $assign->id; 104 $submission->userid = $student->id; 105 $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; 106 $submission->latest = 1; 107 $submission->attemptnumber = 1; 108 $submission->groupid = 0; 109 $submission->timecreated = time(); 110 $submission->timemodified = time(); 111 $DB->insert_record('assign_submission', $submission); 112 113 $grade = new stdClass(); 114 $grade->assignment = $assign->id; 115 $grade->userid = $student->id; 116 $grade->timecreated = time(); 117 $grade->timemodified = $grade->timecreated; 118 $grade->grader = $USER->id; 119 $grade->grade = 75; 120 $grade->attemptnumber = 1; 121 $DB->insert_record('assign_grades', $grade); 122 123 $assignmentids[] = $assign->id; 124 $result = mod_assign_external::get_grades($assignmentids); 125 126 // We need to execute the return values cleaning process to simulate the web service server. 127 $result = external_api::clean_returnvalue(mod_assign_external::get_grades_returns(), $result); 128 129 // Check that the correct grade information for the student is returned. 130 $this->assertEquals(1, count($result['assignments'])); 131 $assignment = $result['assignments'][0]; 132 $this->assertEquals($assign->id, $assignment['assignmentid']); 133 // Should only get the last grade for this student. 134 $this->assertEquals(1, count($assignment['grades'])); 135 $grade = $assignment['grades'][0]; 136 $this->assertEquals($student->id, $grade['userid']); 137 // Should be the last grade (not the first). 138 $this->assertEquals(75, $grade['grade']); 139 } 140 141 /** 142 * Test get_assignments 143 */ 144 public function test_get_assignments() { 145 global $DB, $USER, $CFG; 146 147 $this->resetAfterTest(true); 148 149 $category = self::getDataGenerator()->create_category(array( 150 'name' => 'Test category' 151 )); 152 153 // Create a course. 154 $course1 = self::getDataGenerator()->create_course(array( 155 'idnumber' => 'idnumbercourse1', 156 'fullname' => '<b>Lightwork Course 1</b>', // Adding tags here to check that external_format_string works. 157 'shortname' => '<b>Lightwork Course 1</b>', // Adding tags here to check that external_format_string works. 158 'summary' => 'Lightwork Course 1 description', 159 'summaryformat' => FORMAT_MOODLE, 160 'category' => $category->id 161 )); 162 163 // Create a second course, just for testing. 164 $course2 = self::getDataGenerator()->create_course(array( 165 'idnumber' => 'idnumbercourse2', 166 'fullname' => 'Lightwork Course 2', 167 'summary' => 'Lightwork Course 2 description', 168 'summaryformat' => FORMAT_MOODLE, 169 'category' => $category->id 170 )); 171 172 // Create the assignment module with links to a filerecord. 173 $assign1 = self::getDataGenerator()->create_module('assign', array( 174 'course' => $course1->id, 175 'name' => 'lightwork assignment', 176 'intro' => 'the assignment intro text here <a href="@@PLUGINFILE@@/intro.txt">link</a>', 177 'introformat' => FORMAT_HTML, 178 'markingworkflow' => 1, 179 'markingallocation' => 1 180 )); 181 182 // Add a file as assignment attachment. 183 $context = context_module::instance($assign1->cmid); 184 $filerecord = array('component' => 'mod_assign', 'filearea' => 'intro', 'contextid' => $context->id, 'itemid' => 0, 185 'filename' => 'intro.txt', 'filepath' => '/'); 186 $fs = get_file_storage(); 187 $fs->create_file_from_string($filerecord, 'Test intro file'); 188 189 // Create manual enrolment record. 190 $enrolid = $DB->insert_record('enrol', (object)array( 191 'enrol' => 'manual', 192 'status' => 0, 193 'courseid' => $course1->id 194 )); 195 196 // Create the user and give them capabilities. 197 $context = context_course::instance($course1->id); 198 $roleid = $this->assignUserCapability('moodle/course:view', $context->id); 199 $context = context_module::instance($assign1->cmid); 200 $this->assignUserCapability('mod/assign:view', $context->id, $roleid); 201 202 // Create the user enrolment record. 203 $DB->insert_record('user_enrolments', (object)array( 204 'status' => 0, 205 'enrolid' => $enrolid, 206 'userid' => $USER->id 207 )); 208 209 // Add a file as assignment attachment. 210 $filerecord = array('component' => 'mod_assign', 'filearea' => ASSIGN_INTROATTACHMENT_FILEAREA, 211 'contextid' => $context->id, 'itemid' => 0, 212 'filename' => 'introattachment.txt', 'filepath' => '/'); 213 $fs = get_file_storage(); 214 $fs->create_file_from_string($filerecord, 'Test intro attachment file'); 215 216 $result = mod_assign_external::get_assignments(); 217 218 // We need to execute the return values cleaning process to simulate the web service server. 219 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 220 221 // Check the course and assignment are returned. 222 $this->assertEquals(1, count($result['courses'])); 223 $course = $result['courses'][0]; 224 $this->assertEquals('Lightwork Course 1', $course['fullname']); 225 $this->assertEquals('Lightwork Course 1', $course['shortname']); 226 $this->assertEquals(1, count($course['assignments'])); 227 $assignment = $course['assignments'][0]; 228 $this->assertEquals($assign1->id, $assignment['id']); 229 $this->assertEquals($course1->id, $assignment['course']); 230 $this->assertEquals('lightwork assignment', $assignment['name']); 231 $this->assertContains('the assignment intro text here', $assignment['intro']); 232 // Check the url of the file attatched. 233 $this->assertRegExp('@"' . $CFG->wwwroot . '/webservice/pluginfile.php/\d+/mod_assign/intro/intro\.txt"@', $assignment['intro']); 234 $this->assertEquals(1, $assignment['markingworkflow']); 235 $this->assertEquals(1, $assignment['markingallocation']); 236 $this->assertEquals(0, $assignment['preventsubmissionnotingroup']); 237 238 $this->assertCount(1, $assignment['introattachments']); 239 $this->assertEquals('introattachment.txt', $assignment['introattachments'][0]['filename']); 240 241 // Now, hide the descritption until the submission from date. 242 $DB->set_field('assign', 'alwaysshowdescription', 0, array('id' => $assign1->id)); 243 $DB->set_field('assign', 'allowsubmissionsfromdate', time() + DAYSECS, array('id' => $assign1->id)); 244 245 $result = mod_assign_external::get_assignments(array($course1->id)); 246 247 // We need to execute the return values cleaning process to simulate the web service server. 248 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 249 250 $this->assertEquals(1, count($result['courses'])); 251 $course = $result['courses'][0]; 252 $this->assertEquals('Lightwork Course 1', $course['fullname']); 253 $this->assertEquals(1, count($course['assignments'])); 254 $assignment = $course['assignments'][0]; 255 $this->assertEquals($assign1->id, $assignment['id']); 256 $this->assertEquals($course1->id, $assignment['course']); 257 $this->assertEquals('lightwork assignment', $assignment['name']); 258 $this->assertArrayNotHasKey('intro', $assignment); 259 $this->assertArrayNotHasKey('introattachments', $assignment); 260 $this->assertEquals(1, $assignment['markingworkflow']); 261 $this->assertEquals(1, $assignment['markingallocation']); 262 $this->assertEquals(0, $assignment['preventsubmissionnotingroup']); 263 264 $result = mod_assign_external::get_assignments(array($course2->id)); 265 266 // We need to execute the return values cleaning process to simulate the web service server. 267 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 268 269 $this->assertEquals(0, count($result['courses'])); 270 $this->assertEquals(1, count($result['warnings'])); 271 272 // Test with non-enrolled user, but with view capabilities. 273 $this->setAdminUser(); 274 $result = mod_assign_external::get_assignments(); 275 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 276 $this->assertEquals(0, count($result['courses'])); 277 $this->assertEquals(0, count($result['warnings'])); 278 279 // Expect no courses, because we are not using the special flag. 280 $result = mod_assign_external::get_assignments(array($course1->id)); 281 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 282 $this->assertCount(0, $result['courses']); 283 284 // Now use the special flag to return courses where you are not enroled in. 285 $result = mod_assign_external::get_assignments(array($course1->id), array(), true); 286 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 287 $this->assertCount(1, $result['courses']); 288 289 $course = $result['courses'][0]; 290 $this->assertEquals('Lightwork Course 1', $course['fullname']); 291 $this->assertEquals(1, count($course['assignments'])); 292 $assignment = $course['assignments'][0]; 293 $this->assertEquals($assign1->id, $assignment['id']); 294 $this->assertEquals($course1->id, $assignment['course']); 295 $this->assertEquals('lightwork assignment', $assignment['name']); 296 $this->assertArrayNotHasKey('intro', $assignment); 297 $this->assertArrayNotHasKey('introattachments', $assignment); 298 $this->assertEquals(1, $assignment['markingworkflow']); 299 $this->assertEquals(1, $assignment['markingallocation']); 300 $this->assertEquals(0, $assignment['preventsubmissionnotingroup']); 301 } 302 303 /** 304 * Test get_assignments with submissionstatement. 305 */ 306 public function test_get_assignments_with_submissionstatement() { 307 global $DB, $USER, $CFG; 308 309 $this->resetAfterTest(true); 310 311 // Setup test data. Create 2 assigns, one with requiresubmissionstatement and the other without it. 312 $course = $this->getDataGenerator()->create_course(); 313 $assign = $this->getDataGenerator()->create_module('assign', array( 314 'course' => $course->id, 315 'requiresubmissionstatement' => 1 316 )); 317 $assign2 = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 318 319 // Create student. 320 $student = self::getDataGenerator()->create_user(); 321 322 // Users enrolments. 323 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 324 $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual'); 325 326 // Update the submissionstatement. 327 $submissionstatement = 'This is a fake submission statement.'; 328 set_config('submissionstatement', $submissionstatement, 'assign'); 329 330 $this->setUser($student); 331 332 $result = mod_assign_external::get_assignments(); 333 // We need to execute the return values cleaning process to simulate the web service server. 334 $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); 335 336 // Check that the amount of courses and assignments is right. 337 $this->assertCount(1, $result['courses']); 338 $assignmentsret = $result['courses'][0]['assignments']; 339 $this->assertCount(2, $assignmentsret); 340 341 // Order the returned assignments by ID. 342 usort($assignmentsret, function($a, $b) { 343 return strcmp($a['id'], $b['id']); 344 }); 345 346 // Check that the first assign contains the submission statement. 347 $assignmentret = $assignmentsret[0]; 348 $this->assertEquals($assign->id, $assignmentret['id']); 349 $this->assertEquals(1, $assignmentret['requiresubmissionstatement']); 350 $this->assertEquals($submissionstatement, $assignmentret['submissionstatement']); 351 352 // Check that the second assign does NOT contain the submission statement. 353 $assignmentret = $assignmentsret[1]; 354 $this->assertEquals($assign2->id, $assignmentret['id']); 355 $this->assertEquals(0, $assignmentret['requiresubmissionstatement']); 356 $this->assertArrayNotHasKey('submissionstatement', $assignmentret); 357 } 358 359 /** 360 * Test get_submissions 361 */ 362 public function test_get_submissions() { 363 global $DB, $USER; 364 365 $this->resetAfterTest(true); 366 // Create a course and assignment. 367 $coursedata['idnumber'] = 'idnumbercourse1'; 368 $coursedata['fullname'] = 'Lightwork Course 1'; 369 $coursedata['summary'] = 'Lightwork Course 1 description'; 370 $coursedata['summaryformat'] = FORMAT_MOODLE; 371 $course1 = self::getDataGenerator()->create_course($coursedata); 372 373 $assigndata['course'] = $course1->id; 374 $assigndata['name'] = 'lightwork assignment'; 375 376 $assign1 = self::getDataGenerator()->create_module('assign', $assigndata); 377 378 // Create a student with an online text submission. 379 // First attempt. 380 $student = self::getDataGenerator()->create_user(); 381 $submission = new stdClass(); 382 $submission->assignment = $assign1->id; 383 $submission->userid = $student->id; 384 $submission->timecreated = time(); 385 $submission->timemodified = $submission->timecreated; 386 $submission->status = 'draft'; 387 $submission->attemptnumber = 0; 388 $submission->latest = 0; 389 $sid = $DB->insert_record('assign_submission', $submission); 390 391 // Second attempt. 392 $submission = new stdClass(); 393 $submission->assignment = $assign1->id; 394 $submission->userid = $student->id; 395 $submission->timecreated = time(); 396 $submission->timemodified = $submission->timecreated; 397 $submission->status = 'submitted'; 398 $submission->attemptnumber = 1; 399 $submission->latest = 1; 400 $sid = $DB->insert_record('assign_submission', $submission); 401 $submission->id = $sid; 402 403 $onlinetextsubmission = new stdClass(); 404 $onlinetextsubmission->onlinetext = "<p>online test text</p>"; 405 $onlinetextsubmission->onlineformat = 1; 406 $onlinetextsubmission->submission = $submission->id; 407 $onlinetextsubmission->assignment = $assign1->id; 408 $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission); 409 410 // Create manual enrolment record. 411 $manualenroldata['enrol'] = 'manual'; 412 $manualenroldata['status'] = 0; 413 $manualenroldata['courseid'] = $course1->id; 414 $enrolid = $DB->insert_record('enrol', $manualenroldata); 415 416 // Create a teacher and give them capabilities. 417 $context = context_course::instance($course1->id); 418 $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); 419 $context = context_module::instance($assign1->cmid); 420 $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); 421 422 // Create the teacher's enrolment record. 423 $userenrolmentdata['status'] = 0; 424 $userenrolmentdata['enrolid'] = $enrolid; 425 $userenrolmentdata['userid'] = $USER->id; 426 $DB->insert_record('user_enrolments', $userenrolmentdata); 427 428 $assignmentids[] = $assign1->id; 429 $result = mod_assign_external::get_submissions($assignmentids); 430 $result = external_api::clean_returnvalue(mod_assign_external::get_submissions_returns(), $result); 431 432 // Check the online text submission is returned. 433 $this->assertEquals(1, count($result['assignments'])); 434 $assignment = $result['assignments'][0]; 435 $this->assertEquals($assign1->id, $assignment['assignmentid']); 436 $this->assertEquals(1, count($assignment['submissions'])); 437 $submission = $assignment['submissions'][0]; 438 $this->assertEquals($sid, $submission['id']); 439 $this->assertCount(1, $submission['plugins']); 440 } 441 442 /** 443 * Test get_user_flags 444 */ 445 public function test_get_user_flags() { 446 global $DB, $USER; 447 448 $this->resetAfterTest(true); 449 // Create a course and assignment. 450 $coursedata['idnumber'] = 'idnumbercourse'; 451 $coursedata['fullname'] = 'Lightwork Course'; 452 $coursedata['summary'] = 'Lightwork Course description'; 453 $coursedata['summaryformat'] = FORMAT_MOODLE; 454 $course = self::getDataGenerator()->create_course($coursedata); 455 456 $assigndata['course'] = $course->id; 457 $assigndata['name'] = 'lightwork assignment'; 458 459 $assign = self::getDataGenerator()->create_module('assign', $assigndata); 460 461 // Create a manual enrolment record. 462 $manualenroldata['enrol'] = 'manual'; 463 $manualenroldata['status'] = 0; 464 $manualenroldata['courseid'] = $course->id; 465 $enrolid = $DB->insert_record('enrol', $manualenroldata); 466 467 // Create a teacher and give them capabilities. 468 $context = context_course::instance($course->id); 469 $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); 470 $context = context_module::instance($assign->cmid); 471 $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); 472 473 // Create the teacher's enrolment record. 474 $userenrolmentdata['status'] = 0; 475 $userenrolmentdata['enrolid'] = $enrolid; 476 $userenrolmentdata['userid'] = $USER->id; 477 $DB->insert_record('user_enrolments', $userenrolmentdata); 478 479 // Create a student and give them a user flag record. 480 $student = self::getDataGenerator()->create_user(); 481 $userflag = new stdClass(); 482 $userflag->assignment = $assign->id; 483 $userflag->userid = $student->id; 484 $userflag->locked = 0; 485 $userflag->mailed = 0; 486 $userflag->extensionduedate = 0; 487 $userflag->workflowstate = 'inmarking'; 488 $userflag->allocatedmarker = $USER->id; 489 490 $DB->insert_record('assign_user_flags', $userflag); 491 492 $assignmentids[] = $assign->id; 493 $result = mod_assign_external::get_user_flags($assignmentids); 494 495 // We need to execute the return values cleaning process to simulate the web service server. 496 $result = external_api::clean_returnvalue(mod_assign_external::get_user_flags_returns(), $result); 497 498 // Check that the correct user flag information for the student is returned. 499 $this->assertEquals(1, count($result['assignments'])); 500 $assignment = $result['assignments'][0]; 501 $this->assertEquals($assign->id, $assignment['assignmentid']); 502 // Should be one user flag record. 503 $this->assertEquals(1, count($assignment['userflags'])); 504 $userflag = $assignment['userflags'][0]; 505 $this->assertEquals($student->id, $userflag['userid']); 506 $this->assertEquals(0, $userflag['locked']); 507 $this->assertEquals(0, $userflag['mailed']); 508 $this->assertEquals(0, $userflag['extensionduedate']); 509 $this->assertEquals('inmarking', $userflag['workflowstate']); 510 $this->assertEquals($USER->id, $userflag['allocatedmarker']); 511 } 512 513 /** 514 * Test get_user_mappings 515 */ 516 public function test_get_user_mappings() { 517 global $DB, $USER; 518 519 $this->resetAfterTest(true); 520 // Create a course and assignment. 521 $coursedata['idnumber'] = 'idnumbercourse'; 522 $coursedata['fullname'] = 'Lightwork Course'; 523 $coursedata['summary'] = 'Lightwork Course description'; 524 $coursedata['summaryformat'] = FORMAT_MOODLE; 525 $course = self::getDataGenerator()->create_course($coursedata); 526 527 $assigndata['course'] = $course->id; 528 $assigndata['name'] = 'lightwork assignment'; 529 530 $assign = self::getDataGenerator()->create_module('assign', $assigndata); 531 532 // Create a manual enrolment record. 533 $manualenroldata['enrol'] = 'manual'; 534 $manualenroldata['status'] = 0; 535 $manualenroldata['courseid'] = $course->id; 536 $enrolid = $DB->insert_record('enrol', $manualenroldata); 537 538 // Create a teacher and give them capabilities. 539 $context = context_course::instance($course->id); 540 $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); 541 $context = context_module::instance($assign->cmid); 542 $this->assignUserCapability('mod/assign:revealidentities', $context->id, $roleid); 543 544 // Create the teacher's enrolment record. 545 $userenrolmentdata['status'] = 0; 546 $userenrolmentdata['enrolid'] = $enrolid; 547 $userenrolmentdata['userid'] = $USER->id; 548 $DB->insert_record('user_enrolments', $userenrolmentdata); 549 550 // Create a student and give them a user mapping record. 551 $student = self::getDataGenerator()->create_user(); 552 $mapping = new stdClass(); 553 $mapping->assignment = $assign->id; 554 $mapping->userid = $student->id; 555 556 $DB->insert_record('assign_user_mapping', $mapping); 557 558 $assignmentids[] = $assign->id; 559 $result = mod_assign_external::get_user_mappings($assignmentids); 560 561 // We need to execute the return values cleaning process to simulate the web service server. 562 $result = external_api::clean_returnvalue(mod_assign_external::get_user_mappings_returns(), $result); 563 564 // Check that the correct user mapping information for the student is returned. 565 $this->assertEquals(1, count($result['assignments'])); 566 $assignment = $result['assignments'][0]; 567 $this->assertEquals($assign->id, $assignment['assignmentid']); 568 // Should be one user mapping record. 569 $this->assertEquals(1, count($assignment['mappings'])); 570 $mapping = $assignment['mappings'][0]; 571 $this->assertEquals($student->id, $mapping['userid']); 572 } 573 574 /** 575 * Test lock_submissions 576 * 577 * @expectedException moodle_exception 578 */ 579 public function test_lock_submissions() { 580 global $DB, $USER; 581 582 $this->resetAfterTest(true); 583 // Create a course and assignment and users. 584 $course = self::getDataGenerator()->create_course(); 585 586 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 587 $params['course'] = $course->id; 588 $params['assignsubmission_onlinetext_enabled'] = 1; 589 $instance = $generator->create_instance($params); 590 $cm = get_coursemodule_from_instance('assign', $instance->id); 591 $context = context_module::instance($cm->id); 592 593 $assign = new assign($context, $cm, $course); 594 595 $student1 = self::getDataGenerator()->create_user(); 596 $student2 = self::getDataGenerator()->create_user(); 597 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 598 $this->getDataGenerator()->enrol_user($student1->id, 599 $course->id, 600 $studentrole->id); 601 $this->getDataGenerator()->enrol_user($student2->id, 602 $course->id, 603 $studentrole->id); 604 $teacher = self::getDataGenerator()->create_user(); 605 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 606 $this->getDataGenerator()->enrol_user($teacher->id, 607 $course->id, 608 $teacherrole->id); 609 610 // Create a student1 with an online text submission. 611 // Simulate a submission. 612 $this->setUser($student1); 613 $submission = $assign->get_user_submission($student1->id, true); 614 $data = new stdClass(); 615 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 616 'text'=>'Submission text', 617 'format'=>FORMAT_MOODLE); 618 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 619 $plugin->save($submission, $data); 620 621 // Ready to test. 622 $this->setUser($teacher); 623 $students = array($student1->id, $student2->id); 624 $result = mod_assign_external::lock_submissions($instance->id, $students); 625 $result = external_api::clean_returnvalue(mod_assign_external::lock_submissions_returns(), $result); 626 627 // Check for 0 warnings. 628 $this->assertEquals(0, count($result)); 629 630 $this->setUser($student2); 631 $submission = $assign->get_user_submission($student2->id, true); 632 $data = new stdClass(); 633 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 634 'text'=>'Submission text', 635 'format'=>FORMAT_MOODLE); 636 $notices = array(); 637 $assign->save_submission($data, $notices); 638 } 639 640 /** 641 * Test unlock_submissions 642 */ 643 public function test_unlock_submissions() { 644 global $DB, $USER; 645 646 $this->resetAfterTest(true); 647 // Create a course and assignment and users. 648 $course = self::getDataGenerator()->create_course(); 649 650 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 651 $params['course'] = $course->id; 652 $params['assignsubmission_onlinetext_enabled'] = 1; 653 $instance = $generator->create_instance($params); 654 $cm = get_coursemodule_from_instance('assign', $instance->id); 655 $context = context_module::instance($cm->id); 656 657 $assign = new assign($context, $cm, $course); 658 659 $student1 = self::getDataGenerator()->create_user(); 660 $student2 = self::getDataGenerator()->create_user(); 661 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 662 $this->getDataGenerator()->enrol_user($student1->id, 663 $course->id, 664 $studentrole->id); 665 $this->getDataGenerator()->enrol_user($student2->id, 666 $course->id, 667 $studentrole->id); 668 $teacher = self::getDataGenerator()->create_user(); 669 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 670 $this->getDataGenerator()->enrol_user($teacher->id, 671 $course->id, 672 $teacherrole->id); 673 674 // Create a student1 with an online text submission. 675 // Simulate a submission. 676 $this->setUser($student1); 677 $submission = $assign->get_user_submission($student1->id, true); 678 $data = new stdClass(); 679 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 680 'text'=>'Submission text', 681 'format'=>FORMAT_MOODLE); 682 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 683 $plugin->save($submission, $data); 684 685 // Ready to test. 686 $this->setUser($teacher); 687 $students = array($student1->id, $student2->id); 688 $result = mod_assign_external::lock_submissions($instance->id, $students); 689 $result = external_api::clean_returnvalue(mod_assign_external::lock_submissions_returns(), $result); 690 691 // Check for 0 warnings. 692 $this->assertEquals(0, count($result)); 693 694 $result = mod_assign_external::unlock_submissions($instance->id, $students); 695 $result = external_api::clean_returnvalue(mod_assign_external::unlock_submissions_returns(), $result); 696 697 // Check for 0 warnings. 698 $this->assertEquals(0, count($result)); 699 700 $this->setUser($student2); 701 $submission = $assign->get_user_submission($student2->id, true); 702 $data = new stdClass(); 703 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 704 'text'=>'Submission text', 705 'format'=>FORMAT_MOODLE); 706 $notices = array(); 707 $assign->save_submission($data, $notices); 708 } 709 710 /** 711 * Test submit_for_grading 712 */ 713 public function test_submit_for_grading() { 714 global $DB, $USER; 715 716 $this->resetAfterTest(true); 717 // Create a course and assignment and users. 718 $course = self::getDataGenerator()->create_course(); 719 720 set_config('submissionreceipts', 0, 'assign'); 721 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 722 $params['course'] = $course->id; 723 $params['assignsubmission_onlinetext_enabled'] = 1; 724 $params['submissiondrafts'] = 1; 725 $params['sendnotifications'] = 0; 726 $params['requiresubmissionstatement'] = 1; 727 $instance = $generator->create_instance($params); 728 $cm = get_coursemodule_from_instance('assign', $instance->id); 729 $context = context_module::instance($cm->id); 730 731 $assign = new assign($context, $cm, $course); 732 733 $student1 = self::getDataGenerator()->create_user(); 734 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 735 $this->getDataGenerator()->enrol_user($student1->id, 736 $course->id, 737 $studentrole->id); 738 739 // Create a student1 with an online text submission. 740 // Simulate a submission. 741 $this->setUser($student1); 742 $submission = $assign->get_user_submission($student1->id, true); 743 $data = new stdClass(); 744 $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 745 'text'=>'Submission text', 746 'format'=>FORMAT_MOODLE); 747 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 748 $plugin->save($submission, $data); 749 750 $result = mod_assign_external::submit_for_grading($instance->id, false); 751 $result = external_api::clean_returnvalue(mod_assign_external::submit_for_grading_returns(), $result); 752 753 // Should be 1 fail because the submission statement was not aceptted. 754 $this->assertEquals(1, count($result)); 755 756 $result = mod_assign_external::submit_for_grading($instance->id, true); 757 $result = external_api::clean_returnvalue(mod_assign_external::submit_for_grading_returns(), $result); 758 759 // Check for 0 warnings. 760 $this->assertEquals(0, count($result)); 761 762 $submission = $assign->get_user_submission($student1->id, false); 763 764 $this->assertEquals(ASSIGN_SUBMISSION_STATUS_SUBMITTED, $submission->status); 765 } 766 767 /** 768 * Test save_user_extensions 769 */ 770 public function test_save_user_extensions() { 771 global $DB, $USER; 772 773 $this->resetAfterTest(true); 774 // Create a course and assignment and users. 775 $course = self::getDataGenerator()->create_course(); 776 777 $teacher = self::getDataGenerator()->create_user(); 778 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 779 $this->getDataGenerator()->enrol_user($teacher->id, 780 $course->id, 781 $teacherrole->id); 782 $this->setUser($teacher); 783 784 $now = time(); 785 $yesterday = $now - 24*60*60; 786 $tomorrow = $now + 24*60*60; 787 set_config('submissionreceipts', 0, 'assign'); 788 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 789 $params['course'] = $course->id; 790 $params['submissiondrafts'] = 1; 791 $params['sendnotifications'] = 0; 792 $params['duedate'] = $yesterday; 793 $params['cutoffdate'] = $now - 10; 794 $instance = $generator->create_instance($params); 795 $cm = get_coursemodule_from_instance('assign', $instance->id); 796 $context = context_module::instance($cm->id); 797 798 $assign = new assign($context, $cm, $course); 799 800 $student1 = self::getDataGenerator()->create_user(); 801 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 802 $this->getDataGenerator()->enrol_user($student1->id, 803 $course->id, 804 $studentrole->id); 805 806 $this->setUser($student1); 807 $result = mod_assign_external::submit_for_grading($instance->id, true); 808 $result = external_api::clean_returnvalue(mod_assign_external::submit_for_grading_returns(), $result); 809 810 // Check for 0 warnings. 811 $this->assertEquals(1, count($result)); 812 813 $this->setUser($teacher); 814 $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow)); 815 $result = external_api::clean_returnvalue(mod_assign_external::save_user_extensions_returns(), $result); 816 $this->assertEquals(1, count($result)); 817 818 $this->setUser($teacher); 819 $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($yesterday - 10)); 820 $result = external_api::clean_returnvalue(mod_assign_external::save_user_extensions_returns(), $result); 821 $this->assertEquals(1, count($result)); 822 823 $this->setUser($teacher); 824 $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($tomorrow)); 825 $result = external_api::clean_returnvalue(mod_assign_external::save_user_extensions_returns(), $result); 826 $this->assertEquals(0, count($result)); 827 828 $this->setUser($student1); 829 $result = mod_assign_external::submit_for_grading($instance->id, true); 830 $result = external_api::clean_returnvalue(mod_assign_external::submit_for_grading_returns(), $result); 831 $this->assertEquals(0, count($result)); 832 833 $this->setUser($student1); 834 $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow)); 835 $result = external_api::clean_returnvalue(mod_assign_external::save_user_extensions_returns(), $result); 836 837 } 838 839 /** 840 * Test reveal_identities 841 * 842 * @expectedException required_capability_exception 843 */ 844 public function test_reveal_identities() { 845 global $DB, $USER; 846 847 $this->resetAfterTest(true); 848 // Create a course and assignment and users. 849 $course = self::getDataGenerator()->create_course(); 850 851 $teacher = self::getDataGenerator()->create_user(); 852 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 853 $this->getDataGenerator()->enrol_user($teacher->id, 854 $course->id, 855 $teacherrole->id); 856 $this->setUser($teacher); 857 858 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 859 $params['course'] = $course->id; 860 $params['submissiondrafts'] = 1; 861 $params['sendnotifications'] = 0; 862 $params['blindmarking'] = 1; 863 $instance = $generator->create_instance($params); 864 $cm = get_coursemodule_from_instance('assign', $instance->id); 865 $context = context_module::instance($cm->id); 866 867 $assign = new assign($context, $cm, $course); 868 869 $student1 = self::getDataGenerator()->create_user(); 870 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 871 $this->getDataGenerator()->enrol_user($student1->id, 872 $course->id, 873 $studentrole->id); 874 875 $this->setUser($student1); 876 $result = mod_assign_external::reveal_identities($instance->id); 877 $result = external_api::clean_returnvalue(mod_assign_external::reveal_identities_returns(), $result); 878 $this->assertEquals(1, count($result)); 879 $this->assertEquals(true, $assign->is_blind_marking()); 880 881 $this->setUser($teacher); 882 $result = mod_assign_external::reveal_identities($instance->id); 883 $result = external_api::clean_returnvalue(mod_assign_external::reveal_identities_returns(), $result); 884 $this->assertEquals(0, count($result)); 885 $this->assertEquals(false, $assign->is_blind_marking()); 886 887 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 888 $params['course'] = $course->id; 889 $params['submissiondrafts'] = 1; 890 $params['sendnotifications'] = 0; 891 $params['blindmarking'] = 0; 892 $instance = $generator->create_instance($params); 893 $cm = get_coursemodule_from_instance('assign', $instance->id); 894 $context = context_module::instance($cm->id); 895 896 $assign = new assign($context, $cm, $course); 897 $result = mod_assign_external::reveal_identities($instance->id); 898 $result = external_api::clean_returnvalue(mod_assign_external::reveal_identities_returns(), $result); 899 $this->assertEquals(1, count($result)); 900 $this->assertEquals(false, $assign->is_blind_marking()); 901 902 } 903 904 /** 905 * Test revert_submissions_to_draft 906 */ 907 public function test_revert_submissions_to_draft() { 908 global $DB, $USER; 909 910 $this->resetAfterTest(true); 911 set_config('submissionreceipts', 0, 'assign'); 912 // Create a course and assignment and users. 913 $course = self::getDataGenerator()->create_course(); 914 915 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 916 $params['course'] = $course->id; 917 $params['sendnotifications'] = 0; 918 $params['submissiondrafts'] = 1; 919 $instance = $generator->create_instance($params); 920 $cm = get_coursemodule_from_instance('assign', $instance->id); 921 $context = context_module::instance($cm->id); 922 923 $assign = new assign($context, $cm, $course); 924 925 $student1 = self::getDataGenerator()->create_user(); 926 $student2 = self::getDataGenerator()->create_user(); 927 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 928 $this->getDataGenerator()->enrol_user($student1->id, 929 $course->id, 930 $studentrole->id); 931 $this->getDataGenerator()->enrol_user($student2->id, 932 $course->id, 933 $studentrole->id); 934 $teacher = self::getDataGenerator()->create_user(); 935 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 936 $this->getDataGenerator()->enrol_user($teacher->id, 937 $course->id, 938 $teacherrole->id); 939 940 // Create a student1 with an online text submission. 941 // Simulate a submission. 942 $this->setUser($student1); 943 $result = mod_assign_external::submit_for_grading($instance->id, true); 944 $result = external_api::clean_returnvalue(mod_assign_external::submit_for_grading_returns(), $result); 945 $this->assertEquals(0, count($result)); 946 947 // Ready to test. 948 $this->setUser($teacher); 949 $students = array($student1->id, $student2->id); 950 $result = mod_assign_external::revert_submissions_to_draft($instance->id, array($student1->id)); 951 $result = external_api::clean_returnvalue(mod_assign_external::revert_submissions_to_draft_returns(), $result); 952 953 // Check for 0 warnings. 954 $this->assertEquals(0, count($result)); 955 956 } 957 958 /** 959 * Test save_submission 960 */ 961 public function test_save_submission() { 962 global $DB, $USER; 963 964 $this->resetAfterTest(true); 965 // Create a course and assignment and users. 966 $course = self::getDataGenerator()->create_course(); 967 968 $teacher = self::getDataGenerator()->create_user(); 969 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 970 $this->getDataGenerator()->enrol_user($teacher->id, 971 $course->id, 972 $teacherrole->id); 973 $this->setUser($teacher); 974 975 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 976 $params['course'] = $course->id; 977 $params['assignsubmission_onlinetext_enabled'] = 1; 978 $params['assignsubmission_file_enabled'] = 1; 979 $params['assignsubmission_file_maxfiles'] = 5; 980 $params['assignsubmission_file_maxsizebytes'] = 1024*1024; 981 $instance = $generator->create_instance($params); 982 $cm = get_coursemodule_from_instance('assign', $instance->id); 983 $context = context_module::instance($cm->id); 984 985 $assign = new assign($context, $cm, $course); 986 987 $student1 = self::getDataGenerator()->create_user(); 988 $student2 = self::getDataGenerator()->create_user(); 989 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 990 $this->getDataGenerator()->enrol_user($student1->id, 991 $course->id, 992 $studentrole->id); 993 $this->getDataGenerator()->enrol_user($student2->id, 994 $course->id, 995 $studentrole->id); 996 // Create a student1 with an online text submission. 997 // Simulate a submission. 998 $this->setUser($student1); 999 1000 // Create a file in a draft area. 1001 $draftidfile = file_get_unused_draft_itemid(); 1002 1003 $usercontext = context_user::instance($student1->id); 1004 $filerecord = array( 1005 'contextid' => $usercontext->id, 1006 'component' => 'user', 1007 'filearea' => 'draft', 1008 'itemid' => $draftidfile, 1009 'filepath' => '/', 1010 'filename' => 'testtext.txt', 1011 ); 1012 1013 $fs = get_file_storage(); 1014 $fs->create_file_from_string($filerecord, 'text contents'); 1015 1016 // Create another file in a different draft area. 1017 $draftidonlinetext = file_get_unused_draft_itemid(); 1018 1019 $filerecord = array( 1020 'contextid' => $usercontext->id, 1021 'component' => 'user', 1022 'filearea' => 'draft', 1023 'itemid' => $draftidonlinetext, 1024 'filepath' => '/', 1025 'filename' => 'shouldbeanimage.txt', 1026 ); 1027 1028 $fs->create_file_from_string($filerecord, 'image contents (not really)'); 1029 1030 // Now try a submission. 1031 $submissionpluginparams = array(); 1032 $submissionpluginparams['files_filemanager'] = $draftidfile; 1033 $onlinetexteditorparams = array('text' => '<p>Yeeha!</p>', 1034 'format'=>1, 1035 'itemid'=>$draftidonlinetext); 1036 $submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams; 1037 $result = mod_assign_external::save_submission($instance->id, $submissionpluginparams); 1038 $result = external_api::clean_returnvalue(mod_assign_external::save_submission_returns(), $result); 1039 1040 $this->assertEquals(0, count($result)); 1041 1042 // Set up a due and cutoff passed date. 1043 $instance->duedate = time() - WEEKSECS; 1044 $instance->cutoffdate = time() - WEEKSECS; 1045 $DB->update_record('assign', $instance); 1046 1047 $result = mod_assign_external::save_submission($instance->id, $submissionpluginparams); 1048 $result = external_api::clean_returnvalue(mod_assign_external::save_submission_returns(), $result); 1049 1050 $this->assertCount(1, $result); 1051 $this->assertEquals(get_string('duedatereached', 'assign'), $result[0]['item']); 1052 } 1053 1054 /** 1055 * Test save_grade 1056 */ 1057 public function test_save_grade() { 1058 global $DB, $USER; 1059 1060 $this->resetAfterTest(true); 1061 // Create a course and assignment and users. 1062 $course = self::getDataGenerator()->create_course(); 1063 1064 $teacher = self::getDataGenerator()->create_user(); 1065 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 1066 $this->getDataGenerator()->enrol_user($teacher->id, 1067 $course->id, 1068 $teacherrole->id); 1069 $this->setUser($teacher); 1070 1071 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1072 $params['course'] = $course->id; 1073 $params['assignfeedback_file_enabled'] = 1; 1074 $params['assignfeedback_comments_enabled'] = 1; 1075 $instance = $generator->create_instance($params); 1076 $cm = get_coursemodule_from_instance('assign', $instance->id); 1077 $context = context_module::instance($cm->id); 1078 1079 $assign = new assign($context, $cm, $course); 1080 1081 $student1 = self::getDataGenerator()->create_user(); 1082 $student2 = self::getDataGenerator()->create_user(); 1083 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 1084 $this->getDataGenerator()->enrol_user($student1->id, 1085 $course->id, 1086 $studentrole->id); 1087 $this->getDataGenerator()->enrol_user($student2->id, 1088 $course->id, 1089 $studentrole->id); 1090 // Simulate a grade. 1091 $this->setUser($teacher); 1092 1093 // Create a file in a draft area. 1094 $draftidfile = file_get_unused_draft_itemid(); 1095 1096 $usercontext = context_user::instance($teacher->id); 1097 $filerecord = array( 1098 'contextid' => $usercontext->id, 1099 'component' => 'user', 1100 'filearea' => 'draft', 1101 'itemid' => $draftidfile, 1102 'filepath' => '/', 1103 'filename' => 'testtext.txt', 1104 ); 1105 1106 $fs = get_file_storage(); 1107 $fs->create_file_from_string($filerecord, 'text contents'); 1108 1109 // Now try a grade. 1110 $feedbackpluginparams = array(); 1111 $feedbackpluginparams['files_filemanager'] = $draftidfile; 1112 $feedbackeditorparams = array('text' => 'Yeeha!', 1113 'format' => 1); 1114 $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; 1115 $result = mod_assign_external::save_grade($instance->id, 1116 $student1->id, 1117 50.0, 1118 -1, 1119 true, 1120 'released', 1121 false, 1122 $feedbackpluginparams); 1123 // No warnings. 1124 $this->assertNull($result); 1125 1126 $result = mod_assign_external::get_grades(array($instance->id)); 1127 $result = external_api::clean_returnvalue(mod_assign_external::get_grades_returns(), $result); 1128 1129 $this->assertEquals($result['assignments'][0]['grades'][0]['grade'], '50.0'); 1130 } 1131 1132 /** 1133 * Test save grades with advanced grading data 1134 */ 1135 public function test_save_grades_with_advanced_grading() { 1136 global $DB, $USER; 1137 1138 $this->resetAfterTest(true); 1139 // Create a course and assignment and users. 1140 $course = self::getDataGenerator()->create_course(); 1141 1142 $teacher = self::getDataGenerator()->create_user(); 1143 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1144 $this->getDataGenerator()->enrol_user($teacher->id, 1145 $course->id, 1146 $teacherrole->id); 1147 1148 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1149 $params['course'] = $course->id; 1150 $params['assignfeedback_file_enabled'] = 0; 1151 $params['assignfeedback_comments_enabled'] = 0; 1152 $instance = $generator->create_instance($params); 1153 $cm = get_coursemodule_from_instance('assign', $instance->id); 1154 $context = context_module::instance($cm->id); 1155 1156 $assign = new assign($context, $cm, $course); 1157 1158 $student1 = self::getDataGenerator()->create_user(); 1159 $student2 = self::getDataGenerator()->create_user(); 1160 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 1161 $this->getDataGenerator()->enrol_user($student1->id, 1162 $course->id, 1163 $studentrole->id); 1164 $this->getDataGenerator()->enrol_user($student2->id, 1165 $course->id, 1166 $studentrole->id); 1167 1168 $this->setUser($teacher); 1169 1170 $feedbackpluginparams = array(); 1171 $feedbackpluginparams['files_filemanager'] = 0; 1172 $feedbackeditorparams = array('text' => '', 'format' => 1); 1173 $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; 1174 1175 // Create advanced grading data. 1176 // Create grading area. 1177 $gradingarea = array( 1178 'contextid' => $context->id, 1179 'component' => 'mod_assign', 1180 'areaname' => 'submissions', 1181 'activemethod' => 'rubric' 1182 ); 1183 $areaid = $DB->insert_record('grading_areas', $gradingarea); 1184 1185 // Create a rubric grading definition. 1186 $rubricdefinition = array ( 1187 'areaid' => $areaid, 1188 'method' => 'rubric', 1189 'name' => 'test', 1190 'status' => 20, 1191 'copiedfromid' => 1, 1192 'timecreated' => 1, 1193 'usercreated' => $teacher->id, 1194 'timemodified' => 1, 1195 'usermodified' => $teacher->id, 1196 'timecopied' => 0 1197 ); 1198 $definitionid = $DB->insert_record('grading_definitions', $rubricdefinition); 1199 1200 // Create a criterion with a level. 1201 $rubriccriteria = array ( 1202 'definitionid' => $definitionid, 1203 'sortorder' => 1, 1204 'description' => 'Demonstrate an understanding of disease control', 1205 'descriptionformat' => 0 1206 ); 1207 $criterionid = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria); 1208 $rubriclevel1 = array ( 1209 'criterionid' => $criterionid, 1210 'score' => 50, 1211 'definition' => 'pass', 1212 'definitionformat' => 0 1213 ); 1214 $rubriclevel2 = array ( 1215 'criterionid' => $criterionid, 1216 'score' => 100, 1217 'definition' => 'excellent', 1218 'definitionformat' => 0 1219 ); 1220 $rubriclevel3 = array ( 1221 'criterionid' => $criterionid, 1222 'score' => 0, 1223 'definition' => 'fail', 1224 'definitionformat' => 0 1225 ); 1226 $levelid1 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel1); 1227 $levelid2 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel2); 1228 $levelid3 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel3); 1229 1230 // Create the filling. 1231 $student1filling = array ( 1232 'criterionid' => $criterionid, 1233 'levelid' => $levelid1, 1234 'remark' => 'well done you passed', 1235 'remarkformat' => 0 1236 ); 1237 1238 $student2filling = array ( 1239 'criterionid' => $criterionid, 1240 'levelid' => $levelid2, 1241 'remark' => 'Excellent work', 1242 'remarkformat' => 0 1243 ); 1244 1245 $student1criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student1filling))); 1246 $student1advancedgradingdata = array('rubric' => array('criteria' => $student1criteria)); 1247 1248 $student2criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student2filling))); 1249 $student2advancedgradingdata = array('rubric' => array('criteria' => $student2criteria)); 1250 1251 $grades = array(); 1252 $student1gradeinfo = array(); 1253 $student1gradeinfo['userid'] = $student1->id; 1254 $student1gradeinfo['grade'] = 0; // Ignored since advanced grading is being used. 1255 $student1gradeinfo['attemptnumber'] = -1; 1256 $student1gradeinfo['addattempt'] = true; 1257 $student1gradeinfo['workflowstate'] = 'released'; 1258 $student1gradeinfo['plugindata'] = $feedbackpluginparams; 1259 $student1gradeinfo['advancedgradingdata'] = $student1advancedgradingdata; 1260 $grades[] = $student1gradeinfo; 1261 1262 $student2gradeinfo = array(); 1263 $student2gradeinfo['userid'] = $student2->id; 1264 $student2gradeinfo['grade'] = 0; // Ignored since advanced grading is being used. 1265 $student2gradeinfo['attemptnumber'] = -1; 1266 $student2gradeinfo['addattempt'] = true; 1267 $student2gradeinfo['workflowstate'] = 'released'; 1268 $student2gradeinfo['plugindata'] = $feedbackpluginparams; 1269 $student2gradeinfo['advancedgradingdata'] = $student2advancedgradingdata; 1270 $grades[] = $student2gradeinfo; 1271 1272 $result = mod_assign_external::save_grades($instance->id, false, $grades); 1273 $this->assertNull($result); 1274 1275 $student1grade = $DB->get_record('assign_grades', 1276 array('userid' => $student1->id, 'assignment' => $instance->id), 1277 '*', 1278 MUST_EXIST); 1279 $this->assertEquals($student1grade->grade, '50.0'); 1280 1281 $student2grade = $DB->get_record('assign_grades', 1282 array('userid' => $student2->id, 'assignment' => $instance->id), 1283 '*', 1284 MUST_EXIST); 1285 $this->assertEquals($student2grade->grade, '100.0'); 1286 } 1287 1288 /** 1289 * Test save grades for a team submission 1290 * 1291 * @expectedException invalid_parameter_exception 1292 */ 1293 public function test_save_grades_with_group_submission() { 1294 global $DB, $USER, $CFG; 1295 require_once($CFG->dirroot . '/group/lib.php'); 1296 1297 $this->resetAfterTest(true); 1298 // Create a course and assignment and users. 1299 $course = self::getDataGenerator()->create_course(); 1300 1301 $teacher = self::getDataGenerator()->create_user(); 1302 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1303 $this->getDataGenerator()->enrol_user($teacher->id, 1304 $course->id, 1305 $teacherrole->id); 1306 1307 $groupingdata = array(); 1308 $groupingdata['courseid'] = $course->id; 1309 $groupingdata['name'] = 'Group assignment grouping'; 1310 1311 $grouping = self::getDataGenerator()->create_grouping($groupingdata); 1312 1313 $group1data = array(); 1314 $group1data['courseid'] = $course->id; 1315 $group1data['name'] = 'Team 1'; 1316 $group2data = array(); 1317 $group2data['courseid'] = $course->id; 1318 $group2data['name'] = 'Team 2'; 1319 1320 $group1 = self::getDataGenerator()->create_group($group1data); 1321 $group2 = self::getDataGenerator()->create_group($group2data); 1322 1323 groups_assign_grouping($grouping->id, $group1->id); 1324 groups_assign_grouping($grouping->id, $group2->id); 1325 1326 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1327 $params['course'] = $course->id; 1328 $params['teamsubmission'] = 1; 1329 $params['teamsubmissiongroupingid'] = $grouping->id; 1330 $instance = $generator->create_instance($params); 1331 $cm = get_coursemodule_from_instance('assign', $instance->id); 1332 $context = context_module::instance($cm->id); 1333 1334 $assign = new assign($context, $cm, $course); 1335 1336 $student1 = self::getDataGenerator()->create_user(); 1337 $student2 = self::getDataGenerator()->create_user(); 1338 $student3 = self::getDataGenerator()->create_user(); 1339 $student4 = self::getDataGenerator()->create_user(); 1340 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 1341 $this->getDataGenerator()->enrol_user($student1->id, 1342 $course->id, 1343 $studentrole->id); 1344 $this->getDataGenerator()->enrol_user($student2->id, 1345 $course->id, 1346 $studentrole->id); 1347 $this->getDataGenerator()->enrol_user($student3->id, 1348 $course->id, 1349 $studentrole->id); 1350 $this->getDataGenerator()->enrol_user($student4->id, 1351 $course->id, 1352 $studentrole->id); 1353 1354 groups_add_member($group1->id, $student1->id); 1355 groups_add_member($group1->id, $student2->id); 1356 groups_add_member($group1->id, $student3->id); 1357 groups_add_member($group2->id, $student4->id); 1358 $this->setUser($teacher); 1359 1360 $feedbackpluginparams = array(); 1361 $feedbackpluginparams['files_filemanager'] = 0; 1362 $feedbackeditorparams = array('text' => '', 'format' => 1); 1363 $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; 1364 1365 $grades1 = array(); 1366 $student1gradeinfo = array(); 1367 $student1gradeinfo['userid'] = $student1->id; 1368 $student1gradeinfo['grade'] = 50; 1369 $student1gradeinfo['attemptnumber'] = -1; 1370 $student1gradeinfo['addattempt'] = true; 1371 $student1gradeinfo['workflowstate'] = 'released'; 1372 $student1gradeinfo['plugindata'] = $feedbackpluginparams; 1373 $grades1[] = $student1gradeinfo; 1374 1375 $student2gradeinfo = array(); 1376 $student2gradeinfo['userid'] = $student2->id; 1377 $student2gradeinfo['grade'] = 75; 1378 $student2gradeinfo['attemptnumber'] = -1; 1379 $student2gradeinfo['addattempt'] = true; 1380 $student2gradeinfo['workflowstate'] = 'released'; 1381 $student2gradeinfo['plugindata'] = $feedbackpluginparams; 1382 $grades1[] = $student2gradeinfo; 1383 1384 // Expect an exception since 2 grades have been submitted for the same team. 1385 $result = mod_assign_external::save_grades($instance->id, true, $grades1); 1386 $result = external_api::clean_returnvalue(mod_assign_external::save_grades_returns(), $result); 1387 1388 $grades2 = array(); 1389 $student3gradeinfo = array(); 1390 $student3gradeinfo['userid'] = $student3->id; 1391 $student3gradeinfo['grade'] = 50; 1392 $student3gradeinfo['attemptnumber'] = -1; 1393 $student3gradeinfo['addattempt'] = true; 1394 $student3gradeinfo['workflowstate'] = 'released'; 1395 $student3gradeinfo['plugindata'] = $feedbackpluginparams; 1396 $grades2[] = $student3gradeinfo; 1397 1398 $student4gradeinfo = array(); 1399 $student4gradeinfo['userid'] = $student4->id; 1400 $student4gradeinfo['grade'] = 75; 1401 $student4gradeinfo['attemptnumber'] = -1; 1402 $student4gradeinfo['addattempt'] = true; 1403 $student4gradeinfo['workflowstate'] = 'released'; 1404 $student4gradeinfo['plugindata'] = $feedbackpluginparams; 1405 $grades2[] = $student4gradeinfo; 1406 $result = mod_assign_external::save_grades($instance->id, true, $grades2); 1407 $result = external_api::clean_returnvalue(mod_assign_external::save_grades_returns(), $result); 1408 // There should be no warnings. 1409 $this->assertEquals(0, count($result)); 1410 1411 $student3grade = $DB->get_record('assign_grades', 1412 array('userid' => $student3->id, 'assignment' => $instance->id), 1413 '*', 1414 MUST_EXIST); 1415 $this->assertEquals($student3grade->grade, '50.0'); 1416 1417 $student4grade = $DB->get_record('assign_grades', 1418 array('userid' => $student4->id, 'assignment' => $instance->id), 1419 '*', 1420 MUST_EXIST); 1421 $this->assertEquals($student4grade->grade, '75.0'); 1422 } 1423 1424 /** 1425 * Test copy_previous_attempt 1426 */ 1427 public function test_copy_previous_attempt() { 1428 global $DB, $USER; 1429 1430 $this->resetAfterTest(true); 1431 // Create a course and assignment and users. 1432 $course = self::getDataGenerator()->create_course(); 1433 1434 $teacher = self::getDataGenerator()->create_user(); 1435 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); 1436 $this->getDataGenerator()->enrol_user($teacher->id, 1437 $course->id, 1438 $teacherrole->id); 1439 $this->setUser($teacher); 1440 1441 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1442 $params['course'] = $course->id; 1443 $params['assignsubmission_onlinetext_enabled'] = 1; 1444 $params['assignsubmission_file_enabled'] = 0; 1445 $params['assignfeedback_file_enabled'] = 0; 1446 $params['attemptreopenmethod'] = 'manual'; 1447 $params['maxattempts'] = 5; 1448 $instance = $generator->create_instance($params); 1449 $cm = get_coursemodule_from_instance('assign', $instance->id); 1450 $context = context_module::instance($cm->id); 1451 1452 $assign = new assign($context, $cm, $course); 1453 1454 $student1 = self::getDataGenerator()->create_user(); 1455 $studentrole = $DB->get_record('role', array('shortname'=>'student')); 1456 $this->getDataGenerator()->enrol_user($student1->id, 1457 $course->id, 1458 $studentrole->id); 1459 // Now try a submission. 1460 $this->setUser($student1); 1461 $draftidonlinetext = file_get_unused_draft_itemid(); 1462 $submissionpluginparams = array(); 1463 $onlinetexteditorparams = array('text'=>'Yeeha!', 1464 'format'=>1, 1465 'itemid'=>$draftidonlinetext); 1466 $submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams; 1467 $submissionpluginparams['files_filemanager'] = file_get_unused_draft_itemid(); 1468 $result = mod_assign_external::save_submission($instance->id, $submissionpluginparams); 1469 $result = external_api::clean_returnvalue(mod_assign_external::save_submission_returns(), $result); 1470 1471 $this->setUser($teacher); 1472 // Add a grade and reopen the attempt. 1473 // Now try a grade. 1474 $feedbackpluginparams = array(); 1475 $feedbackpluginparams['files_filemanager'] = file_get_unused_draft_itemid(); 1476 $feedbackeditorparams = array('text'=>'Yeeha!', 1477 'format'=>1); 1478 $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; 1479 $result = mod_assign_external::save_grade($instance->id, 1480 $student1->id, 1481 50.0, 1482 -1, 1483 true, 1484 'released', 1485 false, 1486 $feedbackpluginparams); 1487 $this->assertNull($result); 1488 1489 $this->setUser($student1); 1490 // Now copy the previous attempt. 1491 $result = mod_assign_external::copy_previous_attempt($instance->id); 1492 $result = external_api::clean_returnvalue(mod_assign_external::copy_previous_attempt_returns(), $result); 1493 // No warnings. 1494 $this->assertEquals(0, count($result)); 1495 1496 $this->setUser($teacher); 1497 $result = mod_assign_external::get_submissions(array($instance->id)); 1498 $result = external_api::clean_returnvalue(mod_assign_external::get_submissions_returns(), $result); 1499 1500 // Check we are now on the second attempt. 1501 $this->assertEquals($result['assignments'][0]['submissions'][0]['attemptnumber'], 1); 1502 // Check the plugins data is not empty. 1503 $this->assertNotEmpty($result['assignments'][0]['submissions'][0]['plugins']); 1504 1505 } 1506 1507 /** 1508 * Test set_user_flags 1509 */ 1510 public function test_set_user_flags() { 1511 global $DB, $USER; 1512 1513 $this->resetAfterTest(true); 1514 // Create a course and assignment. 1515 $coursedata['idnumber'] = 'idnumbercourse'; 1516 $coursedata['fullname'] = 'Lightwork Course'; 1517 $coursedata['summary'] = 'Lightwork Course description'; 1518 $coursedata['summaryformat'] = FORMAT_MOODLE; 1519 $course = self::getDataGenerator()->create_course($coursedata); 1520 1521 $assigndata['course'] = $course->id; 1522 $assigndata['name'] = 'lightwork assignment'; 1523 1524 $assign = self::getDataGenerator()->create_module('assign', $assigndata); 1525 1526 // Create a manual enrolment record. 1527 $manualenroldata['enrol'] = 'manual'; 1528 $manualenroldata['status'] = 0; 1529 $manualenroldata['courseid'] = $course->id; 1530 $enrolid = $DB->insert_record('enrol', $manualenroldata); 1531 1532 // Create a teacher and give them capabilities. 1533 $context = context_course::instance($course->id); 1534 $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); 1535 $context = context_module::instance($assign->cmid); 1536 $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); 1537 1538 // Create the teacher's enrolment record. 1539 $userenrolmentdata['status'] = 0; 1540 $userenrolmentdata['enrolid'] = $enrolid; 1541 $userenrolmentdata['userid'] = $USER->id; 1542 $DB->insert_record('user_enrolments', $userenrolmentdata); 1543 1544 // Create a student. 1545 $student = self::getDataGenerator()->create_user(); 1546 1547 // Create test user flags record. 1548 $userflags = array(); 1549 $userflag['userid'] = $student->id; 1550 $userflag['workflowstate'] = 'inmarking'; 1551 $userflag['allocatedmarker'] = $USER->id; 1552 $userflags = array($userflag); 1553 1554 $createduserflags = mod_assign_external::set_user_flags($assign->id, $userflags); 1555 // We need to execute the return values cleaning process to simulate the web service server. 1556 $createduserflags = external_api::clean_returnvalue(mod_assign_external::set_user_flags_returns(), $createduserflags); 1557 1558 $this->assertEquals($student->id, $createduserflags[0]['userid']); 1559 $createduserflag = $DB->get_record('assign_user_flags', array('id' => $createduserflags[0]['id'])); 1560 1561 // Confirm that all data was inserted correctly. 1562 $this->assertEquals($student->id, $createduserflag->userid); 1563 $this->assertEquals($assign->id, $createduserflag->assignment); 1564 $this->assertEquals(0, $createduserflag->locked); 1565 $this->assertEquals(2, $createduserflag->mailed); 1566 $this->assertEquals(0, $createduserflag->extensionduedate); 1567 $this->assertEquals('inmarking', $createduserflag->workflowstate); 1568 $this->assertEquals($USER->id, $createduserflag->allocatedmarker); 1569 1570 // Create update data. 1571 $userflags = array(); 1572 $userflag['userid'] = $createduserflag->userid; 1573 $userflag['workflowstate'] = 'readyforreview'; 1574 $userflags = array($userflag); 1575 1576 $updateduserflags = mod_assign_external::set_user_flags($assign->id, $userflags); 1577 // We need to execute the return values cleaning process to simulate the web service server. 1578 $updateduserflags = external_api::clean_returnvalue(mod_assign_external::set_user_flags_returns(), $updateduserflags); 1579 1580 $this->assertEquals($student->id, $updateduserflags[0]['userid']); 1581 $updateduserflag = $DB->get_record('assign_user_flags', array('id' => $updateduserflags[0]['id'])); 1582 1583 // Confirm that all data was updated correctly. 1584 $this->assertEquals($student->id, $updateduserflag->userid); 1585 $this->assertEquals($assign->id, $updateduserflag->assignment); 1586 $this->assertEquals(0, $updateduserflag->locked); 1587 $this->assertEquals(2, $updateduserflag->mailed); 1588 $this->assertEquals(0, $updateduserflag->extensionduedate); 1589 $this->assertEquals('readyforreview', $updateduserflag->workflowstate); 1590 $this->assertEquals($USER->id, $updateduserflag->allocatedmarker); 1591 } 1592 1593 /** 1594 * Test view_grading_table 1595 * 1596 * @expectedException dml_missing_record_exception 1597 */ 1598 public function test_view_grading_table_invalid_instance() { 1599 global $DB; 1600 1601 $this->resetAfterTest(true); 1602 1603 // Setup test data. 1604 $course = $this->getDataGenerator()->create_course(); 1605 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 1606 $context = context_module::instance($assign->cmid); 1607 $cm = get_coursemodule_from_instance('assign', $assign->id); 1608 1609 // Test invalid instance id. 1610 mod_assign_external::view_grading_table(0); 1611 } 1612 1613 /** 1614 * Test view_grading_table 1615 * 1616 * @expectedException require_login_exception 1617 */ 1618 public function test_view_grading_table_not_enrolled() { 1619 global $DB; 1620 1621 $this->resetAfterTest(true); 1622 1623 // Setup test data. 1624 $course = $this->getDataGenerator()->create_course(); 1625 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 1626 $context = context_module::instance($assign->cmid); 1627 $cm = get_coursemodule_from_instance('assign', $assign->id); 1628 1629 // Test not-enrolled user. 1630 $user = self::getDataGenerator()->create_user(); 1631 $this->setUser($user); 1632 1633 mod_assign_external::view_grading_table($assign->id); 1634 } 1635 1636 /** 1637 * Test view_grading_table 1638 */ 1639 public function test_view_grading_table_correct() { 1640 global $DB; 1641 1642 $this->resetAfterTest(true); 1643 1644 // Setup test data. 1645 $course = $this->getDataGenerator()->create_course(); 1646 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 1647 $context = context_module::instance($assign->cmid); 1648 $cm = get_coursemodule_from_instance('assign', $assign->id); 1649 1650 // Test user with full capabilities. 1651 $user = self::getDataGenerator()->create_user(); 1652 $this->setUser($user); 1653 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1654 $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id); 1655 1656 // Trigger and capture the event. 1657 $sink = $this->redirectEvents(); 1658 1659 $result = mod_assign_external::view_grading_table($assign->id); 1660 $result = external_api::clean_returnvalue(mod_assign_external::view_grading_table_returns(), $result); 1661 1662 $events = $sink->get_events(); 1663 $this->assertCount(1, $events); 1664 $event = array_shift($events); 1665 1666 // Checking that the event contains the expected values. 1667 $this->assertInstanceOf('\mod_assign\event\grading_table_viewed', $event); 1668 $this->assertEquals($context, $event->get_context()); 1669 $moodleurl = new \moodle_url('/mod/assign/view.php', array('id' => $cm->id)); 1670 $this->assertEquals($moodleurl, $event->get_url()); 1671 $this->assertEventContextNotUsed($event); 1672 $this->assertNotEmpty($event->get_name()); 1673 } 1674 1675 /** 1676 * Test view_grading_table 1677 * 1678 * @expectedException require_login_exception 1679 * @expectedExceptionMessage Course or activity not accessible. (Activity is hidden) 1680 */ 1681 public function test_view_grading_table_without_capability() { 1682 global $DB; 1683 1684 $this->resetAfterTest(true); 1685 1686 // Setup test data. 1687 $course = $this->getDataGenerator()->create_course(); 1688 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 1689 $context = context_module::instance($assign->cmid); 1690 $cm = get_coursemodule_from_instance('assign', $assign->id); 1691 1692 // Test user with no capabilities. 1693 $user = self::getDataGenerator()->create_user(); 1694 $this->setUser($user); 1695 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1696 $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id); 1697 1698 // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles. 1699 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1700 assign_capability('mod/assign:view', CAP_PROHIBIT, $teacherrole->id, $context->id); 1701 // Empty all the caches that may be affected by this change. 1702 accesslib_clear_all_caches_for_unit_testing(); 1703 course_modinfo::clear_instance_cache(); 1704 1705 mod_assign_external::view_grading_table($assign->id); 1706 } 1707 1708 /** 1709 * Test subplugins availability 1710 */ 1711 public function test_subplugins_availability() { 1712 global $CFG; 1713 1714 require_once($CFG->dirroot . '/mod/assign/adminlib.php'); 1715 $this->resetAfterTest(true); 1716 1717 // Hide assignment file submissiong plugin. 1718 $pluginmanager = new assign_plugin_manager('assignsubmission'); 1719 $pluginmanager->hide_plugin('file'); 1720 $parameters = mod_assign_external::save_submission_parameters(); 1721 1722 $this->assertTrue(!isset($parameters->keys['plugindata']->keys['files_filemanager'])); 1723 1724 // Show it again and check that the value is returned as optional. 1725 $pluginmanager->show_plugin('file'); 1726 $parameters = mod_assign_external::save_submission_parameters(); 1727 $this->assertTrue(isset($parameters->keys['plugindata']->keys['files_filemanager'])); 1728 $this->assertEquals(VALUE_OPTIONAL, $parameters->keys['plugindata']->keys['files_filemanager']->required); 1729 1730 // Hide feedback file submissiong plugin. 1731 $pluginmanager = new assign_plugin_manager('assignfeedback'); 1732 $pluginmanager->hide_plugin('file'); 1733 1734 $parameters = mod_assign_external::save_grade_parameters(); 1735 1736 $this->assertTrue(!isset($parameters->keys['plugindata']->keys['files_filemanager'])); 1737 1738 // Show it again and check that the value is returned as optional. 1739 $pluginmanager->show_plugin('file'); 1740 $parameters = mod_assign_external::save_grade_parameters(); 1741 1742 $this->assertTrue(isset($parameters->keys['plugindata']->keys['files_filemanager'])); 1743 $this->assertEquals(VALUE_OPTIONAL, $parameters->keys['plugindata']->keys['files_filemanager']->required); 1744 1745 // Check a different one. 1746 $pluginmanager->show_plugin('comments'); 1747 $this->assertTrue(isset($parameters->keys['plugindata']->keys['assignfeedbackcomments_editor'])); 1748 $this->assertEquals(VALUE_OPTIONAL, $parameters->keys['plugindata']->keys['assignfeedbackcomments_editor']->required); 1749 } 1750 1751 /** 1752 * Test test_view_submission_status 1753 */ 1754 public function test_view_submission_status() { 1755 global $DB; 1756 1757 $this->resetAfterTest(true); 1758 1759 $this->setAdminUser(); 1760 // Setup test data. 1761 $course = $this->getDataGenerator()->create_course(); 1762 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id)); 1763 $context = context_module::instance($assign->cmid); 1764 $cm = get_coursemodule_from_instance('assign', $assign->id); 1765 1766 // Test invalid instance id. 1767 try { 1768 mod_assign_external::view_submission_status(0); 1769 $this->fail('Exception expected due to invalid mod_assign instance id.'); 1770 } catch (moodle_exception $e) { 1771 $this->assertEquals('invalidrecord', $e->errorcode); 1772 } 1773 1774 // Test not-enrolled user. 1775 $user = self::getDataGenerator()->create_user(); 1776 $this->setUser($user); 1777 try { 1778 mod_assign_external::view_submission_status($assign->id); 1779 $this->fail('Exception expected due to not enrolled user.'); 1780 } catch (moodle_exception $e) { 1781 $this->assertEquals('requireloginerror', $e->errorcode); 1782 } 1783 1784 // Test user with full capabilities. 1785 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 1786 $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id); 1787 1788 // Trigger and capture the event. 1789 $sink = $this->redirectEvents(); 1790 1791 $result = mod_assign_external::view_submission_status($assign->id); 1792 $result = external_api::clean_returnvalue(mod_assign_external::view_submission_status_returns(), $result); 1793 1794 $events = $sink->get_events(); 1795 $this->assertCount(1, $events); 1796 $event = array_shift($events); 1797 1798 // Checking that the event contains the expected values. 1799 $this->assertInstanceOf('\mod_assign\event\submission_status_viewed', $event); 1800 $this->assertEquals($context, $event->get_context()); 1801 $moodleurl = new \moodle_url('/mod/assign/view.php', array('id' => $cm->id)); 1802 $this->assertEquals($moodleurl, $event->get_url()); 1803 $this->assertEventContextNotUsed($event); 1804 $this->assertNotEmpty($event->get_name()); 1805 1806 // Test user with no capabilities. 1807 // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles. 1808 assign_capability('mod/assign:view', CAP_PROHIBIT, $studentrole->id, $context->id); 1809 accesslib_clear_all_caches_for_unit_testing(); 1810 course_modinfo::clear_instance_cache(); 1811 1812 try { 1813 mod_assign_external::view_submission_status($assign->id); 1814 $this->fail('Exception expected due to missing capability.'); 1815 } catch (moodle_exception $e) { 1816 $this->assertEquals('requireloginerror', $e->errorcode); 1817 } 1818 } 1819 1820 /** 1821 * Create a submission for testing the get_submission_status function. 1822 * @param boolean $submitforgrading whether to submit for grading the submission 1823 * @return array an array containing all the required data for testing 1824 */ 1825 private function create_submission_for_testing_status($submitforgrading = false) { 1826 global $DB, $CFG; 1827 require_once($CFG->dirroot . '/mod/assign/tests/base_test.php'); 1828 1829 // Create a course and assignment and users. 1830 $course = self::getDataGenerator()->create_course(); 1831 1832 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1833 $params = array( 1834 'course' => $course->id, 1835 'assignsubmission_file_maxfiles' => 1, 1836 'assignsubmission_file_maxsizebytes' => 1024 * 1024, 1837 'assignsubmission_onlinetext_enabled' => 1, 1838 'assignsubmission_file_enabled' => 1, 1839 'submissiondrafts' => 1, 1840 'assignfeedback_file_enabled' => 1, 1841 'assignfeedback_comments_enabled' => 1, 1842 'attemptreopenmethod' => ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL, 1843 'sendnotifications' => 0 1844 ); 1845 1846 set_config('submissionreceipts', 0, 'assign'); 1847 1848 $instance = $generator->create_instance($params); 1849 $cm = get_coursemodule_from_instance('assign', $instance->id); 1850 $context = context_module::instance($cm->id); 1851 1852 $assign = new testable_assign($context, $cm, $course); 1853 1854 $student1 = self::getDataGenerator()->create_user(); 1855 $student2 = self::getDataGenerator()->create_user(); 1856 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 1857 $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); 1858 $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); 1859 $teacher = self::getDataGenerator()->create_user(); 1860 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 1861 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); 1862 1863 $this->setUser($student1); 1864 1865 // Create a student1 with an online text submission. 1866 // Simulate a submission. 1867 $submission = $assign->get_user_submission($student1->id, true); 1868 1869 $data = new stdClass(); 1870 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(), 1871 'text' => 'Submission text', 1872 'format' => FORMAT_MOODLE); 1873 1874 $draftidfile = file_get_unused_draft_itemid(); 1875 $usercontext = context_user::instance($student1->id); 1876 $filerecord = array( 1877 'contextid' => $usercontext->id, 1878 'component' => 'user', 1879 'filearea' => 'draft', 1880 'itemid' => $draftidfile, 1881 'filepath' => '/', 1882 'filename' => 't.txt', 1883 ); 1884 $fs = get_file_storage(); 1885 $fs->create_file_from_string($filerecord, 'text contents'); 1886 1887 $data->files_filemanager = $draftidfile; 1888 1889 $notices = array(); 1890 $assign->save_submission($data, $notices); 1891 1892 if ($submitforgrading) { 1893 // Now, submit the draft for grading. 1894 $notices = array(); 1895 1896 $data = new stdClass; 1897 $data->userid = $student1->id; 1898 $assign->submit_for_grading($data, $notices); 1899 } 1900 1901 return array($assign, $instance, $student1, $student2, $teacher); 1902 } 1903 1904 /** 1905 * Test get_submission_status for a draft submission. 1906 */ 1907 public function test_get_submission_status_in_draft_status() { 1908 $this->resetAfterTest(true); 1909 1910 list($assign, $instance, $student1, $student2, $teacher) = $this->create_submission_for_testing_status(); 1911 1912 $result = mod_assign_external::get_submission_status($assign->get_instance()->id); 1913 // We expect debugging because of the $PAGE object, this won't happen in a normal WS request. 1914 $this->assertDebuggingCalled(); 1915 1916 $result = external_api::clean_returnvalue(mod_assign_external::get_submission_status_returns(), $result); 1917 1918 // The submission is now in draft mode. 1919 $this->assertCount(0, $result['warnings']); 1920 $this->assertFalse(isset($result['gradingsummary'])); 1921 $this->assertFalse(isset($result['feedback'])); 1922 $this->assertFalse(isset($result['previousattempts'])); 1923 1924 $this->assertTrue($result['lastattempt']['submissionsenabled']); 1925 $this->assertTrue($result['lastattempt']['canedit']); 1926 $this->assertTrue($result['lastattempt']['cansubmit']); 1927 $this->assertFalse($result['lastattempt']['locked']); 1928 $this->assertFalse($result['lastattempt']['graded']); 1929 $this->assertEmpty($result['lastattempt']['extensionduedate']); 1930 $this->assertFalse($result['lastattempt']['blindmarking']); 1931 $this->assertCount(0, $result['lastattempt']['submissiongroupmemberswhoneedtosubmit']); 1932 $this->assertEquals('notgraded', $result['lastattempt']['gradingstatus']); 1933 1934 $this->assertEquals($student1->id, $result['lastattempt']['submission']['userid']); 1935 $this->assertEquals(0, $result['lastattempt']['submission']['attemptnumber']); 1936 $this->assertEquals('draft', $result['lastattempt']['submission']['status']); 1937 $this->assertEquals(0, $result['lastattempt']['submission']['groupid']); 1938 $this->assertEquals($assign->get_instance()->id, $result['lastattempt']['submission']['assignment']); 1939 $this->assertEquals(1, $result['lastattempt']['submission']['latest']); 1940 1941 // Map plugins based on their type - we can't rely on them being in a 1942 // particular order, especially if 3rd party plugins are installed. 1943 $submissionplugins = array(); 1944 foreach ($result['lastattempt']['submission']['plugins'] as $plugin) { 1945 $submissionplugins[$plugin['type']] = $plugin; 1946 } 1947 $this->assertEquals('Submission text', $submissionplugins['onlinetext']['editorfields'][0]['text']); 1948 $this->assertEquals('/', $submissionplugins['file']['fileareas'][0]['files'][0]['filepath']); 1949 $this->assertEquals('t.txt', $submissionplugins['file']['fileareas'][0]['files'][0]['filename']); 1950 } 1951 1952 /** 1953 * Test get_submission_status for a submitted submission. 1954 */ 1955 public function test_get_submission_status_in_submission_status() { 1956 $this->resetAfterTest(true); 1957 1958 list($assign, $instance, $student1, $student2, $teacher) = $this->create_submission_for_testing_status(true); 1959 1960 $result = mod_assign_external::get_submission_status($assign->get_instance()->id); 1961 // We expect debugging because of the $PAGE object, this won't happen in a normal WS request. 1962 $this->assertDebuggingCalled(); 1963 $result = external_api::clean_returnvalue(mod_assign_external::get_submission_status_returns(), $result); 1964 1965 $this->assertCount(0, $result['warnings']); 1966 $this->assertFalse(isset($result['gradingsummary'])); 1967 $this->assertFalse(isset($result['feedback'])); 1968 $this->assertFalse(isset($result['previousattempts'])); 1969 1970 $this->assertTrue($result['lastattempt']['submissionsenabled']); 1971 $this->assertFalse($result['lastattempt']['canedit']); 1972 $this->assertFalse($result['lastattempt']['cansubmit']); 1973 $this->assertFalse($result['lastattempt']['locked']); 1974 $this->assertFalse($result['lastattempt']['graded']); 1975 $this->assertEmpty($result['lastattempt']['extensionduedate']); 1976 $this->assertFalse($result['lastattempt']['blindmarking']); 1977 $this->assertCount(0, $result['lastattempt']['submissiongroupmemberswhoneedtosubmit']); 1978 $this->assertEquals('notgraded', $result['lastattempt']['gradingstatus']); 1979 1980 } 1981 1982 /** 1983 * Test get_submission_status using the teacher role. 1984 */ 1985 public function test_get_submission_status_in_submission_status_for_teacher() { 1986 $this->resetAfterTest(true); 1987 1988 list($assign, $instance, $student1, $student2, $teacher) = $this->create_submission_for_testing_status(true); 1989 1990 // Now, as teacher, see the grading summary. 1991 $this->setUser($teacher); 1992 $result = mod_assign_external::get_submission_status($assign->get_instance()->id); 1993 // We expect debugging because of the $PAGE object, this won't happen in a normal WS request. 1994 $this->assertDebuggingCalled(); 1995 $result = external_api::clean_returnvalue(mod_assign_external::get_submission_status_returns(), $result); 1996 1997 $this->assertCount(0, $result['warnings']); 1998 $this->assertFalse(isset($result['lastattempt'])); 1999 $this->assertFalse(isset($result['feedback'])); 2000 $this->assertFalse(isset($result['previousattempts'])); 2001 2002 $this->assertEquals(2, $result['gradingsummary']['participantcount']); 2003 $this->assertEquals(0, $result['gradingsummary']['submissiondraftscount']); 2004 $this->assertEquals(1, $result['gradingsummary']['submissionsenabled']); 2005 $this->assertEquals(1, $result['gradingsummary']['submissionssubmittedcount']); 2006 $this->assertEquals(1, $result['gradingsummary']['submissionsneedgradingcount']); 2007 $this->assertFalse($result['gradingsummary']['warnofungroupedusers']); 2008 } 2009 2010 /** 2011 * Test get_submission_status for a reopened submission. 2012 */ 2013 public function test_get_submission_status_in_reopened_status() { 2014 global $USER; 2015 2016 $this->resetAfterTest(true); 2017 2018 list($assign, $instance, $student1, $student2, $teacher) = $this->create_submission_for_testing_status(true); 2019 2020 $this->setUser($teacher); 2021 // Grade and reopen. 2022 $feedbackpluginparams = array(); 2023 $feedbackpluginparams['files_filemanager'] = file_get_unused_draft_itemid(); 2024 $feedbackeditorparams = array('text' => 'Yeeha!', 2025 'format' => 1); 2026 $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; 2027 $result = mod_assign_external::save_grade($instance->id, 2028 $student1->id, 2029 50.0, 2030 -1, 2031 false, 2032 'released', 2033 false, 2034 $feedbackpluginparams); 2035 $USER->ignoresesskey = true; 2036 $assign->testable_process_add_attempt($student1->id); 2037 2038 $this->setUser($student1); 2039 2040 $result = mod_assign_external::get_submission_status($assign->get_instance()->id); 2041 // We expect debugging because of the $PAGE object, this won't happen in a normal WS request. 2042 $this->assertDebuggingCalled(); 2043 $result = external_api::clean_returnvalue(mod_assign_external::get_submission_status_returns(), $result); 2044 2045 $this->assertCount(0, $result['warnings']); 2046 $this->assertFalse(isset($result['gradingsummary'])); 2047 2048 $this->assertTrue($result['lastattempt']['submissionsenabled']); 2049 $this->assertTrue($result['lastattempt']['canedit']); 2050 $this->assertFalse($result['lastattempt']['cansubmit']); 2051 $this->assertFalse($result['lastattempt']['locked']); 2052 $this->assertFalse($result['lastattempt']['graded']); 2053 $this->assertEmpty($result['lastattempt']['extensionduedate']); 2054 $this->assertFalse($result['lastattempt']['blindmarking']); 2055 $this->assertCount(0, $result['lastattempt']['submissiongroupmemberswhoneedtosubmit']); 2056 $this->assertEquals('notgraded', $result['lastattempt']['gradingstatus']); 2057 2058 // Check new attempt reopened. 2059 $this->assertEquals($student1->id, $result['lastattempt']['submission']['userid']); 2060 $this->assertEquals(1, $result['lastattempt']['submission']['attemptnumber']); 2061 $this->assertEquals('reopened', $result['lastattempt']['submission']['status']); 2062 $this->assertEquals(0, $result['lastattempt']['submission']['groupid']); 2063 $this->assertEquals($assign->get_instance()->id, $result['lastattempt']['submission']['assignment']); 2064 $this->assertEquals(1, $result['lastattempt']['submission']['latest']); 2065 $this->assertCount(3, $result['lastattempt']['submission']['plugins']); 2066 2067 // Now see feedback and the attempts history (remember, is a submission reopened). 2068 // Only 2 fields (no grade, no plugins data). 2069 $this->assertCount(2, $result['feedback']); 2070 2071 // One previous attempt. 2072 $this->assertCount(1, $result['previousattempts']); 2073 $this->assertEquals(0, $result['previousattempts'][0]['attemptnumber']); 2074 $this->assertEquals(50, $result['previousattempts'][0]['grade']['grade']); 2075 $this->assertEquals($teacher->id, $result['previousattempts'][0]['grade']['grader']); 2076 $this->assertEquals($student1->id, $result['previousattempts'][0]['grade']['userid']); 2077 2078 // Map plugins based on their type - we can't rely on them being in a 2079 // particular order, especially if 3rd party plugins are installed. 2080 $feedbackplugins = array(); 2081 foreach ($result['previousattempts'][0]['feedbackplugins'] as $plugin) { 2082 $feedbackplugins[$plugin['type']] = $plugin; 2083 } 2084 $this->assertEquals('Yeeha!', $feedbackplugins['comments']['editorfields'][0]['text']); 2085 2086 $submissionplugins = array(); 2087 foreach ($result['previousattempts'][0]['submission']['plugins'] as $plugin) { 2088 $submissionplugins[$plugin['type']] = $plugin; 2089 } 2090 $this->assertEquals('Submission text', $submissionplugins['onlinetext']['editorfields'][0]['text']); 2091 $this->assertEquals('/', $submissionplugins['file']['fileareas'][0]['files'][0]['filepath']); 2092 $this->assertEquals('t.txt', $submissionplugins['file']['fileareas'][0]['files'][0]['filename']); 2093 } 2094 2095 /** 2096 * Test access control for get_submission_status. 2097 * 2098 * @expectedException required_capability_exception 2099 */ 2100 public function test_get_submission_status_access_control() { 2101 $this->resetAfterTest(true); 2102 2103 list($assign, $instance, $student1, $student2, $teacher) = $this->create_submission_for_testing_status(); 2104 2105 $this->setUser($student2); 2106 2107 // Access control test. 2108 mod_assign_external::get_submission_status($assign->get_instance()->id, $student1->id); 2109 2110 } 2111 2112 /** 2113 * get_participant should throw an excaption if the requested assignment doesn't exist. 2114 * 2115 * @expectedException moodle_exception 2116 */ 2117 public function test_get_participant_no_assignment() { 2118 $this->resetAfterTest(true); 2119 mod_assign_external::get_participant('-1', '-1', false); 2120 } 2121 2122 /** 2123 * get_participant should throw a require_login_exception if the user doesn't have access 2124 * to view assignments. 2125 * 2126 * @expectedException require_login_exception 2127 */ 2128 public function test_get_participant_no_view_capability() { 2129 global $DB; 2130 $this->resetAfterTest(true); 2131 2132 $result = $this->create_assign_with_student_and_teacher(); 2133 $assign = $result['assign']; 2134 $student = $result['student']; 2135 $course = $result['course']; 2136 $context = context_course::instance($course->id); 2137 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 2138 2139 $this->setUser($student); 2140 assign_capability('mod/assign:view', CAP_PROHIBIT, $studentrole->id, $context->id, true); 2141 2142 mod_assign_external::get_participant($assign->id, $student->id, false); 2143 } 2144 2145 /** 2146 * get_participant should throw a required_capability_exception if the user doesn't have access 2147 * to view assignment grades. 2148 * 2149 * @expectedException required_capability_exception 2150 */ 2151 public function test_get_participant_no_grade_capability() { 2152 global $DB; 2153 $this->resetAfterTest(true); 2154 2155 $result = $this->create_assign_with_student_and_teacher(); 2156 $assign = $result['assign']; 2157 $student = $result['student']; 2158 $teacher = $result['teacher']; 2159 $course = $result['course']; 2160 $context = context_course::instance($course->id); 2161 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2162 2163 $this->setUser($teacher); 2164 assign_capability('mod/assign:viewgrades', CAP_PROHIBIT, $teacherrole->id, $context->id, true); 2165 assign_capability('mod/assign:grade', CAP_PROHIBIT, $teacherrole->id, $context->id, true); 2166 accesslib_clear_all_caches_for_unit_testing(); 2167 2168 mod_assign_external::get_participant($assign->id, $student->id, false); 2169 } 2170 2171 /** 2172 * get_participant should throw an exception if the user isn't enrolled in the course. 2173 * 2174 * @expectedException moodle_exception 2175 */ 2176 public function test_get_participant_no_participant() { 2177 global $DB; 2178 $this->resetAfterTest(true); 2179 2180 $result = $this->create_assign_with_student_and_teacher(array('blindmarking' => true)); 2181 $student = $this->getDataGenerator()->create_user(); 2182 $assign = $result['assign']; 2183 $teacher = $result['teacher']; 2184 2185 $this->setUser($teacher); 2186 2187 $result = mod_assign_external::get_participant($assign->id, $student->id, false); 2188 } 2189 2190 /** 2191 * get_participant should return a summarised list of details with a different fullname if blind 2192 * marking is on for the requested assignment. 2193 */ 2194 public function test_get_participant_blind_marking() { 2195 global $DB; 2196 $this->resetAfterTest(true); 2197 2198 $result = $this->create_assign_with_student_and_teacher(array('blindmarking' => true)); 2199 $assign = $result['assign']; 2200 $student = $result['student']; 2201 $teacher = $result['teacher']; 2202 $course = $result['course']; 2203 $context = context_course::instance($course->id); 2204 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2205 2206 $this->setUser($teacher); 2207 2208 $result = mod_assign_external::get_participant($assign->id, $student->id, true); 2209 $this->assertEquals($student->id, $result['id']); 2210 $this->assertFalse(fullname($student) == $result['fullname']); 2211 $this->assertFalse($result['submitted']); 2212 $this->assertFalse($result['requiregrading']); 2213 $this->assertTrue($result['blindmarking']); 2214 // Make sure we don't get any additional info. 2215 $this->assertTrue(empty($result['user'])); 2216 } 2217 2218 /** 2219 * get_participant should return a summarised list of details if requested. 2220 */ 2221 public function test_get_participant_no_user() { 2222 global $DB; 2223 $this->resetAfterTest(true); 2224 2225 $result = $this->create_assign_with_student_and_teacher(); 2226 $assignmodule = $result['assign']; 2227 $student = $result['student']; 2228 $teacher = $result['teacher']; 2229 $course = $result['course']; 2230 $context = context_course::instance($course->id); 2231 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2232 2233 // Create an assign instance to save a submission. 2234 set_config('submissionreceipts', 0, 'assign'); 2235 2236 $cm = get_coursemodule_from_instance('assign', $assignmodule->id); 2237 $context = context_module::instance($cm->id); 2238 2239 $assign = new assign($context, $cm, $course); 2240 2241 $this->setUser($student); 2242 2243 // Simulate a submission. 2244 $data = new stdClass(); 2245 $data->onlinetext_editor = array( 2246 'itemid' => file_get_unused_draft_itemid(), 2247 'text' => 'Student submission text', 2248 'format' => FORMAT_MOODLE 2249 ); 2250 2251 $notices = array(); 2252 $assign->save_submission($data, $notices); 2253 2254 $data = new stdClass; 2255 $data->userid = $student->id; 2256 $assign->submit_for_grading($data, array()); 2257 2258 $this->setUser($teacher); 2259 2260 $result = mod_assign_external::get_participant($assignmodule->id, $student->id, false); 2261 $this->assertEquals($student->id, $result['id']); 2262 $this->assertEquals(fullname($student), $result['fullname']); 2263 $this->assertTrue($result['submitted']); 2264 $this->assertTrue($result['requiregrading']); 2265 $this->assertFalse($result['blindmarking']); 2266 // Make sure we don't get any additional info. 2267 $this->assertTrue(empty($result['user'])); 2268 } 2269 2270 /** 2271 * get_participant should return user details if requested. 2272 */ 2273 public function test_get_participant_full_details() { 2274 global $DB; 2275 $this->resetAfterTest(true); 2276 2277 $result = $this->create_assign_with_student_and_teacher(); 2278 $assign = $result['assign']; 2279 $student = $result['student']; 2280 $teacher = $result['teacher']; 2281 $course = $result['course']; 2282 $context = context_course::instance($course->id); 2283 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2284 2285 $this->setUser($teacher); 2286 2287 $result = mod_assign_external::get_participant($assign->id, $student->id, true); 2288 // Check some of the extended properties we get when requesting the user. 2289 $this->assertEquals($student->id, $result['id']); 2290 // We should get user infomation back. 2291 $user = $result['user']; 2292 $this->assertFalse(empty($user)); 2293 $this->assertEquals($student->firstname, $user['firstname']); 2294 $this->assertEquals($student->lastname, $user['lastname']); 2295 $this->assertEquals($student->email, $user['email']); 2296 } 2297 2298 /** 2299 * get_participant should return group details if a group submission was 2300 * submitted. 2301 */ 2302 public function test_get_participant_group_submission() { 2303 global $DB, $CFG; 2304 require_once($CFG->dirroot . '/mod/assign/tests/base_test.php'); 2305 2306 $this->resetAfterTest(true); 2307 2308 $result = $this->create_assign_with_student_and_teacher(array( 2309 'assignsubmission_onlinetext_enabled' => 1, 2310 'teamsubmission' => 1 2311 )); 2312 $assignmodule = $result['assign']; 2313 $student = $result['student']; 2314 $teacher = $result['teacher']; 2315 $course = $result['course']; 2316 $context = context_course::instance($course->id); 2317 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2318 $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 2319 $cm = get_coursemodule_from_instance('assign', $assignmodule->id); 2320 $context = context_module::instance($cm->id); 2321 $assign = new testable_assign($context, $cm, $course); 2322 2323 groups_add_member($group, $student); 2324 2325 $this->setUser($student); 2326 $submission = $assign->get_group_submission($student->id, $group->id, true); 2327 $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED; 2328 $assign->testable_update_submission($submission, $student->id, true, false); 2329 $data = new stdClass(); 2330 $data->onlinetext_editor = array('itemid' => file_get_unused_draft_itemid(), 2331 'text' => 'Submission text', 2332 'format' => FORMAT_MOODLE); 2333 $plugin = $assign->get_submission_plugin_by_type('onlinetext'); 2334 $plugin->save($submission, $data); 2335 2336 $this->setUser($teacher); 2337 2338 $result = mod_assign_external::get_participant($assignmodule->id, $student->id, false); 2339 // Check some of the extended properties we get when not requesting a summary. 2340 $this->assertEquals($student->id, $result['id']); 2341 $this->assertEquals($group->id, $result['groupid']); 2342 $this->assertEquals($group->name, $result['groupname']); 2343 } 2344 2345 /** 2346 * Test for mod_assign_external::list_participants(). 2347 * 2348 * @throws coding_exception 2349 */ 2350 public function test_list_participants_user_info_with_special_characters() { 2351 global $CFG, $DB; 2352 $this->resetAfterTest(true); 2353 $CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution'; 2354 2355 $data = $this->create_assign_with_student_and_teacher(); 2356 $assignment = $data['assign']; 2357 $teacher = $data['teacher']; 2358 2359 // Set data for student info that contain special characters. 2360 $student = $data['student']; 2361 $student->idnumber = '<\'"1am@wesome&c00l"\'>'; 2362 $student->phone1 = '+63 (999) 888-7777'; 2363 $student->phone2 = '(011) [15]4-123-4567'; 2364 $student->department = 'Arts & Sciences & \' " ¢ £ © € ¥ ® < >'; 2365 $student->institution = 'University of Awesome People & \' " ¢ £ © € ¥ ® < >'; 2366 // Assert that we have valid user data. 2367 $this->assertTrue(core_user::validate($student)); 2368 // Update the user record. 2369 $DB->update_record('user', $student); 2370 2371 $this->setUser($teacher); 2372 $participants = mod_assign_external::list_participants($assignment->id, 0, '', 0, 0, false); 2373 $this->assertCount(1, $participants); 2374 2375 // Asser that we have a valid response data. 2376 $response = external_api::clean_returnvalue(mod_assign_external::list_participants_returns(), $participants); 2377 $this->assertEquals($response, $participants); 2378 2379 // Check participant data. 2380 $participant = $participants[0]; 2381 $this->assertEquals($student->idnumber, $participant['idnumber']); 2382 $this->assertEquals($student->email, $participant['email']); 2383 $this->assertEquals($student->phone1, $participant['phone1']); 2384 $this->assertEquals($student->phone2, $participant['phone2']); 2385 $this->assertEquals($student->department, $participant['department']); 2386 $this->assertEquals($student->institution, $participant['institution']); 2387 } 2388 2389 /** 2390 * Test for the type of the user-related properties in mod_assign_external::list_participants_returns(). 2391 */ 2392 public function test_list_participants_returns_user_property_types() { 2393 // Get user properties. 2394 $userdesc = core_user_external::user_description(); 2395 $this->assertTrue(isset($userdesc->keys)); 2396 $userproperties = array_keys($userdesc->keys); 2397 2398 // Get returns description for mod_assign_external::list_participants_returns(). 2399 $listreturns = mod_assign_external::list_participants_returns(); 2400 $this->assertTrue(isset($listreturns->content)); 2401 $listreturnsdesc = $listreturns->content->keys; 2402 2403 // Iterate over list returns description's keys. 2404 foreach ($listreturnsdesc as $key => $desc) { 2405 // Check if key exists in user properties and the description has a type attribute. 2406 if (in_array($key, $userproperties) && isset($desc->type)) { 2407 try { 2408 // The core_user::get_property_type() method might throw a coding_exception since 2409 // core_user_external::user_description() might contain properties that are not yet included in 2410 // core_user's $propertiescache. 2411 $propertytype = core_user::get_property_type($key); 2412 2413 // Assert that user-related property types match those of the defined in core_user. 2414 $this->assertEquals($propertytype, $desc->type); 2415 } catch (coding_exception $e) { 2416 // All good. 2417 } 2418 } 2419 } 2420 } 2421 2422 /** 2423 * Create a a course, assignment module instance, student and teacher and enrol them in 2424 * the course. 2425 * 2426 * @param array $params parameters to be provided to the assignment module creation 2427 * @return array containing the course, assignment module, student and teacher 2428 */ 2429 private function create_assign_with_student_and_teacher($params = array()) { 2430 global $DB; 2431 2432 $course = $this->getDataGenerator()->create_course(); 2433 $params = array_merge(array( 2434 'course' => $course->id, 2435 'name' => 'assignment', 2436 'intro' => 'assignment intro text', 2437 ), $params); 2438 2439 // Create a course and assignment and users. 2440 $assign = $this->getDataGenerator()->create_module('assign', $params); 2441 2442 $cm = get_coursemodule_from_instance('assign', $assign->id); 2443 $context = context_module::instance($cm->id); 2444 2445 $student = $this->getDataGenerator()->create_user(); 2446 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 2447 $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); 2448 $teacher = $this->getDataGenerator()->create_user(); 2449 $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); 2450 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); 2451 2452 assign_capability('mod/assign:view', CAP_ALLOW, $teacherrole->id, $context->id, true); 2453 assign_capability('mod/assign:viewgrades', CAP_ALLOW, $teacherrole->id, $context->id, true); 2454 assign_capability('mod/assign:grade', CAP_ALLOW, $teacherrole->id, $context->id, true); 2455 accesslib_clear_all_caches_for_unit_testing(); 2456 2457 return array( 2458 'course' => $course, 2459 'assign' => $assign, 2460 'student' => $student, 2461 'teacher' => $teacher 2462 ); 2463 } 2464 2465 /** 2466 * Test test_view_assign 2467 */ 2468 public function test_view_assign() { 2469 global $CFG; 2470 2471 $CFG->enablecompletion = 1; 2472 $this->resetAfterTest(); 2473 2474 $this->setAdminUser(); 2475 // Setup test data. 2476 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 2477 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), 2478 array('completion' => 2, 'completionview' => 1)); 2479 $context = context_module::instance($assign->cmid); 2480 $cm = get_coursemodule_from_instance('assign', $assign->id); 2481 2482 $result = mod_assign_external::view_assign($assign->id); 2483 $result = external_api::clean_returnvalue(mod_assign_external::view_assign_returns(), $result); 2484 $this->assertTrue($result['status']); 2485 $this->assertEmpty($result['warnings']); 2486 2487 // Check completion status. 2488 $completion = new completion_info($course); 2489 $completiondata = $completion->get_data($cm); 2490 $this->assertEquals(1, $completiondata->completionstate); 2491 } 2492 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |