. defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->dirroot . '/webservice/tests/helpers.php'); /** * External mod assign functions unit tests * * @package mod_assign * @category external * @copyright 2012 Paul Charsley * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mod_assign_external_testcase extends externallib_advanced_testcase { /** * Tests set up */ protected function setUp() { global $CFG; require_once($CFG->dirroot . '/mod/assign/externallib.php'); } /** * Test get_grades */ public function test_get_grades() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment. $coursedata['idnumber'] = 'idnumbercourse'; $coursedata['fullname'] = 'Lightwork Course'; $coursedata['summary'] = 'Lightwork Course description'; $coursedata['summaryformat'] = FORMAT_MOODLE; $course = self::getDataGenerator()->create_course($coursedata); $assigndata['course'] = $course->id; $assigndata['name'] = 'lightwork assignment'; $assign = self::getDataGenerator()->create_module('assign', $assigndata); // Create a manual enrolment record. $manualenroldata['enrol'] = 'manual'; $manualenroldata['status'] = 0; $manualenroldata['courseid'] = $course->id; $enrolid = $DB->insert_record('enrol', $manualenroldata); // Create a teacher and give them capabilities. $context = context_course::instance($course->id); $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); $context = context_module::instance($assign->cmid); $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); // Create the teacher's enrolment record. $userenrolmentdata['status'] = 0; $userenrolmentdata['enrolid'] = $enrolid; $userenrolmentdata['userid'] = $USER->id; $DB->insert_record('user_enrolments', $userenrolmentdata); // Create a student and give them 2 grades (for 2 attempts). $student = self::getDataGenerator()->create_user(); $submission = new stdClass(); $submission->assignment = $assign->id; $submission->userid = $student->id; $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; $submission->latest = 0; $submission->attemptnumber = 0; $submission->groupid = 0; $submission->timecreated = time(); $submission->timemodified = time(); $DB->insert_record('assign_submission', $submission); $grade = new stdClass(); $grade->assignment = $assign->id; $grade->userid = $student->id; $grade->timecreated = time(); $grade->timemodified = $grade->timecreated; $grade->grader = $USER->id; $grade->grade = 50; $grade->attemptnumber = 0; $DB->insert_record('assign_grades', $grade); $submission = new stdClass(); $submission->assignment = $assign->id; $submission->userid = $student->id; $submission->status = ASSIGN_SUBMISSION_STATUS_NEW; $submission->latest = 1; $submission->attemptnumber = 1; $submission->groupid = 0; $submission->timecreated = time(); $submission->timemodified = time(); $DB->insert_record('assign_submission', $submission); $grade = new stdClass(); $grade->assignment = $assign->id; $grade->userid = $student->id; $grade->timecreated = time(); $grade->timemodified = $grade->timecreated; $grade->grader = $USER->id; $grade->grade = 75; $grade->attemptnumber = 1; $DB->insert_record('assign_grades', $grade); $assignmentids[] = $assign->id; $result = mod_assign_external::get_grades($assignmentids); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_grades_returns(), $result); // Check that the correct grade information for the student is returned. $this->assertEquals(1, count($result['assignments'])); $assignment = $result['assignments'][0]; $this->assertEquals($assign->id, $assignment['assignmentid']); // Should only get the last grade for this student. $this->assertEquals(1, count($assignment['grades'])); $grade = $assignment['grades'][0]; $this->assertEquals($student->id, $grade['userid']); // Should be the last grade (not the first). $this->assertEquals(75, $grade['grade']); } /** * Test get_assignments */ public function test_get_assignments() { global $DB, $USER; $this->resetAfterTest(true); $category = self::getDataGenerator()->create_category(array( 'name' => 'Test category' )); // Create a course. $course1 = self::getDataGenerator()->create_course(array( 'idnumber' => 'idnumbercourse1', 'fullname' => 'Lightwork Course 1', 'summary' => 'Lightwork Course 1 description', 'summaryformat' => FORMAT_MOODLE, 'category' => $category->id )); // Create a second course, just for testing. $course2 = self::getDataGenerator()->create_course(array( 'idnumber' => 'idnumbercourse2', 'fullname' => 'Lightwork Course 2', 'summary' => 'Lightwork Course 2 description', 'summaryformat' => FORMAT_MOODLE, 'category' => $category->id )); // Create the assignment module. $assign1 = self::getDataGenerator()->create_module('assign', array( 'course' => $course1->id, 'name' => 'lightwork assignment', 'markingworkflow' => 1, 'markingallocation' => 1 )); // Create manual enrolment record. $enrolid = $DB->insert_record('enrol', (object)array( 'enrol' => 'manual', 'status' => 0, 'courseid' => $course1->id )); // Create the user and give them capabilities. $context = context_course::instance($course1->id); $roleid = $this->assignUserCapability('moodle/course:view', $context->id); $context = context_module::instance($assign1->cmid); $this->assignUserCapability('mod/assign:view', $context->id, $roleid); // Create the user enrolment record. $DB->insert_record('user_enrolments', (object)array( 'status' => 0, 'enrolid' => $enrolid, 'userid' => $USER->id )); $result = mod_assign_external::get_assignments(); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); // Check the course and assignment are returned. $this->assertEquals(1, count($result['courses'])); $course = $result['courses'][0]; $this->assertEquals('Lightwork Course 1', $course['fullname']); $this->assertEquals(1, count($course['assignments'])); $assignment = $course['assignments'][0]; $this->assertEquals($assign1->id, $assignment['id']); $this->assertEquals($course1->id, $assignment['course']); $this->assertEquals('lightwork assignment', $assignment['name']); $this->assertEquals(1, $assignment['markingworkflow']); $this->assertEquals(1, $assignment['markingallocation']); $result = mod_assign_external::get_assignments(array($course1->id)); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); $this->assertEquals(1, count($result['courses'])); $course = $result['courses'][0]; $this->assertEquals('Lightwork Course 1', $course['fullname']); $this->assertEquals(1, count($course['assignments'])); $assignment = $course['assignments'][0]; $this->assertEquals($assign1->id, $assignment['id']); $this->assertEquals($course1->id, $assignment['course']); $this->assertEquals('lightwork assignment', $assignment['name']); $this->assertEquals(1, $assignment['markingworkflow']); $this->assertEquals(1, $assignment['markingallocation']); $result = mod_assign_external::get_assignments(array($course2->id)); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); $this->assertEquals(0, count($result['courses'])); $this->assertEquals(1, count($result['warnings'])); } /** * Test get_submissions */ public function test_get_submissions() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment. $coursedata['idnumber'] = 'idnumbercourse1'; $coursedata['fullname'] = 'Lightwork Course 1'; $coursedata['summary'] = 'Lightwork Course 1 description'; $coursedata['summaryformat'] = FORMAT_MOODLE; $course1 = self::getDataGenerator()->create_course($coursedata); $assigndata['course'] = $course1->id; $assigndata['name'] = 'lightwork assignment'; $assign1 = self::getDataGenerator()->create_module('assign', $assigndata); // Create a student with an online text submission. // First attempt. $student = self::getDataGenerator()->create_user(); $submission = new stdClass(); $submission->assignment = $assign1->id; $submission->userid = $student->id; $submission->timecreated = time(); $submission->timemodified = $submission->timecreated; $submission->status = 'draft'; $submission->attemptnumber = 0; $submission->latest = 0; $sid = $DB->insert_record('assign_submission', $submission); // Second attempt. $submission = new stdClass(); $submission->assignment = $assign1->id; $submission->userid = $student->id; $submission->timecreated = time(); $submission->timemodified = $submission->timecreated; $submission->status = 'submitted'; $submission->attemptnumber = 1; $submission->latest = 1; $sid = $DB->insert_record('assign_submission', $submission); $submission->id = $sid; $onlinetextsubmission = new stdClass(); $onlinetextsubmission->onlinetext = "

online test text

"; $onlinetextsubmission->onlineformat = 1; $onlinetextsubmission->submission = $submission->id; $onlinetextsubmission->assignment = $assign1->id; $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission); // Create manual enrolment record. $manualenroldata['enrol'] = 'manual'; $manualenroldata['status'] = 0; $manualenroldata['courseid'] = $course1->id; $enrolid = $DB->insert_record('enrol', $manualenroldata); // Create a teacher and give them capabilities. $context = context_course::instance($course1->id); $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); $context = context_module::instance($assign1->cmid); $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); // Create the teacher's enrolment record. $userenrolmentdata['status'] = 0; $userenrolmentdata['enrolid'] = $enrolid; $userenrolmentdata['userid'] = $USER->id; $DB->insert_record('user_enrolments', $userenrolmentdata); $assignmentids[] = $assign1->id; $result = mod_assign_external::get_submissions($assignmentids); // Check the online text submission is returned. $this->assertEquals(1, count($result['assignments'])); $assignment = $result['assignments'][0]; $this->assertEquals($assign1->id, $assignment['assignmentid']); $this->assertEquals(1, count($assignment['submissions'])); $submission = $assignment['submissions'][0]; $this->assertEquals($sid, $submission['id']); $this->assertGreaterThanOrEqual(3, count($submission['plugins'])); $plugins = $submission['plugins']; foreach ($plugins as $plugin) { $foundonlinetext = false; if ($plugin['type'] == 'onlinetext') { $foundonlinetext = true; break; } } $this->assertTrue($foundonlinetext); } /** * Test get_user_flags */ public function test_get_user_flags() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment. $coursedata['idnumber'] = 'idnumbercourse'; $coursedata['fullname'] = 'Lightwork Course'; $coursedata['summary'] = 'Lightwork Course description'; $coursedata['summaryformat'] = FORMAT_MOODLE; $course = self::getDataGenerator()->create_course($coursedata); $assigndata['course'] = $course->id; $assigndata['name'] = 'lightwork assignment'; $assign = self::getDataGenerator()->create_module('assign', $assigndata); // Create a manual enrolment record. $manualenroldata['enrol'] = 'manual'; $manualenroldata['status'] = 0; $manualenroldata['courseid'] = $course->id; $enrolid = $DB->insert_record('enrol', $manualenroldata); // Create a teacher and give them capabilities. $context = context_course::instance($course->id); $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); $context = context_module::instance($assign->cmid); $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); // Create the teacher's enrolment record. $userenrolmentdata['status'] = 0; $userenrolmentdata['enrolid'] = $enrolid; $userenrolmentdata['userid'] = $USER->id; $DB->insert_record('user_enrolments', $userenrolmentdata); // Create a student and give them a user flag record. $student = self::getDataGenerator()->create_user(); $userflag = new stdClass(); $userflag->assignment = $assign->id; $userflag->userid = $student->id; $userflag->locked = 0; $userflag->mailed = 0; $userflag->extensionduedate = 0; $userflag->workflowstate = 'inmarking'; $userflag->allocatedmarker = $USER->id; $DB->insert_record('assign_user_flags', $userflag); $assignmentids[] = $assign->id; $result = mod_assign_external::get_user_flags($assignmentids); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_user_flags_returns(), $result); // Check that the correct user flag information for the student is returned. $this->assertEquals(1, count($result['assignments'])); $assignment = $result['assignments'][0]; $this->assertEquals($assign->id, $assignment['assignmentid']); // Should be one user flag record. $this->assertEquals(1, count($assignment['userflags'])); $userflag = $assignment['userflags'][0]; $this->assertEquals($student->id, $userflag['userid']); $this->assertEquals(0, $userflag['locked']); $this->assertEquals(0, $userflag['mailed']); $this->assertEquals(0, $userflag['extensionduedate']); $this->assertEquals('inmarking', $userflag['workflowstate']); $this->assertEquals($USER->id, $userflag['allocatedmarker']); } /** * Test get_user_mappings */ public function test_get_user_mappings() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment. $coursedata['idnumber'] = 'idnumbercourse'; $coursedata['fullname'] = 'Lightwork Course'; $coursedata['summary'] = 'Lightwork Course description'; $coursedata['summaryformat'] = FORMAT_MOODLE; $course = self::getDataGenerator()->create_course($coursedata); $assigndata['course'] = $course->id; $assigndata['name'] = 'lightwork assignment'; $assign = self::getDataGenerator()->create_module('assign', $assigndata); // Create a manual enrolment record. $manualenroldata['enrol'] = 'manual'; $manualenroldata['status'] = 0; $manualenroldata['courseid'] = $course->id; $enrolid = $DB->insert_record('enrol', $manualenroldata); // Create a teacher and give them capabilities. $context = context_course::instance($course->id); $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); $context = context_module::instance($assign->cmid); $this->assignUserCapability('mod/assign:revealidentities', $context->id, $roleid); // Create the teacher's enrolment record. $userenrolmentdata['status'] = 0; $userenrolmentdata['enrolid'] = $enrolid; $userenrolmentdata['userid'] = $USER->id; $DB->insert_record('user_enrolments', $userenrolmentdata); // Create a student and give them a user mapping record. $student = self::getDataGenerator()->create_user(); $mapping = new stdClass(); $mapping->assignment = $assign->id; $mapping->userid = $student->id; $DB->insert_record('assign_user_mapping', $mapping); $assignmentids[] = $assign->id; $result = mod_assign_external::get_user_mappings($assignmentids); // We need to execute the return values cleaning process to simulate the web service server. $result = external_api::clean_returnvalue(mod_assign_external::get_user_mappings_returns(), $result); // Check that the correct user mapping information for the student is returned. $this->assertEquals(1, count($result['assignments'])); $assignment = $result['assignments'][0]; $this->assertEquals($assign->id, $assignment['assignmentid']); // Should be one user mapping record. $this->assertEquals(1, count($assignment['mappings'])); $mapping = $assignment['mappings'][0]; $this->assertEquals($student->id, $mapping['userid']); } /** * Test lock_submissions */ public function test_lock_submissions() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignsubmission_onlinetext_enabled'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); // Create a student1 with an online text submission. // Simulate a submission. $this->setUser($student1); $submission = $assign->get_user_submission($student1->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 'text'=>'Submission text', 'format'=>FORMAT_MOODLE); $plugin = $assign->get_submission_plugin_by_type('onlinetext'); $plugin->save($submission, $data); // Ready to test. $this->setUser($teacher); $students = array($student1->id, $student2->id); $result = mod_assign_external::lock_submissions($instance->id, $students); // Check for 0 warnings. $this->assertEquals(0, count($result)); $this->setUser($student2); $submission = $assign->get_user_submission($student2->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 'text'=>'Submission text', 'format'=>FORMAT_MOODLE); $notices = array(); $this->setExpectedException('moodle_exception'); $assign->save_submission($data, $notices); } /** * Test unlock_submissions */ public function test_unlock_submissions() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignsubmission_onlinetext_enabled'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); // Create a student1 with an online text submission. // Simulate a submission. $this->setUser($student1); $submission = $assign->get_user_submission($student1->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 'text'=>'Submission text', 'format'=>FORMAT_MOODLE); $plugin = $assign->get_submission_plugin_by_type('onlinetext'); $plugin->save($submission, $data); // Ready to test. $this->setUser($teacher); $students = array($student1->id, $student2->id); $result = mod_assign_external::lock_submissions($instance->id, $students); // Check for 0 warnings. $this->assertEquals(0, count($result)); $result = mod_assign_external::unlock_submissions($instance->id, $students); // Check for 0 warnings. $this->assertEquals(0, count($result)); $this->setUser($student2); $submission = $assign->get_user_submission($student2->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 'text'=>'Submission text', 'format'=>FORMAT_MOODLE); $notices = array(); $assign->save_submission($data, $notices); } /** * Test submit_for_grading */ public function test_submit_for_grading() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); set_config('submissionreceipts', 0, 'assign'); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignsubmission_onlinetext_enabled'] = 1; $params['submissiondrafts'] = 1; $params['sendnotifications'] = 0; $params['requiresubmissionstatement'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); // Create a student1 with an online text submission. // Simulate a submission. $this->setUser($student1); $submission = $assign->get_user_submission($student1->id, true); $data = new stdClass(); $data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(), 'text'=>'Submission text', 'format'=>FORMAT_MOODLE); $plugin = $assign->get_submission_plugin_by_type('onlinetext'); $plugin->save($submission, $data); $result = mod_assign_external::submit_for_grading($instance->id, false); // Should be 1 fail because the submission statement was not aceptted. $this->assertEquals(1, count($result)); $result = mod_assign_external::submit_for_grading($instance->id, true); // Check for 0 warnings. $this->assertEquals(0, count($result)); $submission = $assign->get_user_submission($student1->id, false); $this->assertEquals(ASSIGN_SUBMISSION_STATUS_SUBMITTED, $submission->status); } /** * Test save_user_extensions */ public function test_save_user_extensions() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $this->setUser($teacher); $now = time(); $yesterday = $now - 24*60*60; $tomorrow = $now + 24*60*60; set_config('submissionreceipts', 0, 'assign'); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['submissiondrafts'] = 1; $params['sendnotifications'] = 0; $params['duedate'] = $yesterday; $params['cutoffdate'] = $now - 10; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->setUser($student1); $result = mod_assign_external::submit_for_grading($instance->id, true); // Check for 0 warnings. $this->assertEquals(1, count($result)); $this->setUser($teacher); $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow)); $this->assertEquals(1, count($result)); $this->setUser($teacher); $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($yesterday - 10)); $this->assertEquals(1, count($result)); $this->setUser($teacher); $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($tomorrow)); $this->assertEquals(0, count($result)); $this->setUser($student1); $result = mod_assign_external::submit_for_grading($instance->id, true); $this->assertEquals(0, count($result)); $this->setUser($student1); $result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow)); } /** * Test reveal_identities */ public function test_reveal_identities() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $this->setUser($teacher); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['submissiondrafts'] = 1; $params['sendnotifications'] = 0; $params['blindmarking'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->setUser($student1); $this->setExpectedException('required_capability_exception'); $result = mod_assign_external::reveal_identities($instance->id); $this->assertEquals(1, count($result)); $this->assertEquals(true, $assign->is_blind_marking()); $this->setUser($teacher); $result = mod_assign_external::reveal_identities($instance->id); $this->assertEquals(0, count($result)); $this->assertEquals(false, $assign->is_blind_marking()); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['submissiondrafts'] = 1; $params['sendnotifications'] = 0; $params['blindmarking'] = 0; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $result = mod_assign_external::reveal_identities($instance->id); $this->assertEquals(1, count($result)); $this->assertEquals(false, $assign->is_blind_marking()); } /** * Test revert_submissions_to_draft */ public function test_revert_submissions_to_draft() { global $DB, $USER; $this->resetAfterTest(true); set_config('submissionreceipts', 0, 'assign'); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['sendnotifications'] = 0; $params['submissiondrafts'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); // Create a student1 with an online text submission. // Simulate a submission. $this->setUser($student1); $result = mod_assign_external::submit_for_grading($instance->id, true); $this->assertEquals(0, count($result)); // Ready to test. $this->setUser($teacher); $students = array($student1->id, $student2->id); $result = mod_assign_external::revert_submissions_to_draft($instance->id, array($student1->id)); // Check for 0 warnings. $this->assertEquals(0, count($result)); } /** * Test save_submission */ public function test_save_submission() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $this->setUser($teacher); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignsubmission_onlinetext_enabled'] = 1; $params['assignsubmission_file_enabled'] = 1; $params['assignsubmission_file_maxfiles'] = 5; $params['assignsubmission_file_maxsizebytes'] = 1024*1024; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); // Create a student1 with an online text submission. // Simulate a submission. $this->setUser($student1); // Create a file in a draft area. $draftidfile = file_get_unused_draft_itemid(); $usercontext = context_user::instance($student1->id); $filerecord = array( 'contextid' => $usercontext->id, 'component' => 'user', 'filearea' => 'draft', 'itemid' => $draftidfile, 'filepath' => '/', 'filename' => 'testtext.txt', ); $fs = get_file_storage(); $fs->create_file_from_string($filerecord, 'text contents'); // Create another file in a different draft area. $draftidonlinetext = file_get_unused_draft_itemid(); $filerecord = array( 'contextid' => $usercontext->id, 'component' => 'user', 'filearea' => 'draft', 'itemid' => $draftidonlinetext, 'filepath' => '/', 'filename' => 'shouldbeanimage.txt', ); $fs->create_file_from_string($filerecord, 'image contents (not really)'); // Now try a submission. $submissionpluginparams = array(); $submissionpluginparams['files_filemanager'] = $draftidfile; $onlinetexteditorparams = array('text'=>'Yeeha!', 'format'=>1, 'itemid'=>$draftidonlinetext); $submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams; $result = mod_assign_external::save_submission($instance->id, $submissionpluginparams); $this->assertEquals(0, count($result)); } /** * Test save_grade */ public function test_save_grade() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $this->setUser($teacher); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignfeedback_file_enabled'] = 1; $params['assignfeedback_comments_enabled'] = 1; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); // Simulate a grade. $this->setUser($teacher); // Create a file in a draft area. $draftidfile = file_get_unused_draft_itemid(); $usercontext = context_user::instance($teacher->id); $filerecord = array( 'contextid' => $usercontext->id, 'component' => 'user', 'filearea' => 'draft', 'itemid' => $draftidfile, 'filepath' => '/', 'filename' => 'testtext.txt', ); $fs = get_file_storage(); $fs->create_file_from_string($filerecord, 'text contents'); // Now try a grade. $feedbackpluginparams = array(); $feedbackpluginparams['files_filemanager'] = $draftidfile; $feedbackeditorparams = array('text' => 'Yeeha!', 'format' => 1); $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; $result = mod_assign_external::save_grade($instance->id, $student1->id, 50.0, -1, true, 'released', false, $feedbackpluginparams); // No warnings. $this->assertEquals(0, count($result)); $result = mod_assign_external::get_grades(array($instance->id)); $this->assertEquals($result['assignments'][0]['grades'][0]['grade'], '50.0'); } /** * Test save grades with advanced grading data */ public function test_save_grades_with_advanced_grading() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignfeedback_file_enabled'] = 0; $params['assignfeedback_comments_enabled'] = 0; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); $this->setUser($teacher); $feedbackpluginparams = array(); $feedbackpluginparams['files_filemanager'] = 0; $feedbackeditorparams = array('text' => '', 'format' => 1); $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; // Create advanced grading data. // Create grading area. $gradingarea = array( 'contextid' => $context->id, 'component' => 'mod_assign', 'areaname' => 'submissions', 'activemethod' => 'rubric' ); $areaid = $DB->insert_record('grading_areas', $gradingarea); // Create a rubric grading definition. $rubricdefinition = array ( 'areaid' => $areaid, 'method' => 'rubric', 'name' => 'test', 'status' => 20, 'copiedfromid' => 1, 'timecreated' => 1, 'usercreated' => $teacher->id, 'timemodified' => 1, 'usermodified' => $teacher->id, 'timecopied' => 0 ); $definitionid = $DB->insert_record('grading_definitions', $rubricdefinition); // Create a criterion with a level. $rubriccriteria = array ( 'definitionid' => $definitionid, 'sortorder' => 1, 'description' => 'Demonstrate an understanding of disease control', 'descriptionformat' => 0 ); $criterionid = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria); $rubriclevel1 = array ( 'criterionid' => $criterionid, 'score' => 50, 'definition' => 'pass', 'definitionformat' => 0 ); $rubriclevel2 = array ( 'criterionid' => $criterionid, 'score' => 100, 'definition' => 'excellent', 'definitionformat' => 0 ); $rubriclevel3 = array ( 'criterionid' => $criterionid, 'score' => 0, 'definition' => 'fail', 'definitionformat' => 0 ); $levelid1 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel1); $levelid2 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel2); $levelid3 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel3); // Create the filling. $student1filling = array ( 'criterionid' => $criterionid, 'levelid' => $levelid1, 'remark' => 'well done you passed', 'remarkformat' => 0 ); $student2filling = array ( 'criterionid' => $criterionid, 'levelid' => $levelid2, 'remark' => 'Excellent work', 'remarkformat' => 0 ); $student1criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student1filling))); $student1advancedgradingdata = array('rubric' => array('criteria' => $student1criteria)); $student2criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student2filling))); $student2advancedgradingdata = array('rubric' => array('criteria' => $student2criteria)); $grades = array(); $student1gradeinfo = array(); $student1gradeinfo['userid'] = $student1->id; $student1gradeinfo['grade'] = 0; // Ignored since advanced grading is being used. $student1gradeinfo['attemptnumber'] = -1; $student1gradeinfo['addattempt'] = true; $student1gradeinfo['workflowstate'] = 'released'; $student1gradeinfo['plugindata'] = $feedbackpluginparams; $student1gradeinfo['advancedgradingdata'] = $student1advancedgradingdata; $grades[] = $student1gradeinfo; $student2gradeinfo = array(); $student2gradeinfo['userid'] = $student2->id; $student2gradeinfo['grade'] = 0; // Ignored since advanced grading is being used. $student2gradeinfo['attemptnumber'] = -1; $student2gradeinfo['addattempt'] = true; $student2gradeinfo['workflowstate'] = 'released'; $student2gradeinfo['plugindata'] = $feedbackpluginparams; $student2gradeinfo['advancedgradingdata'] = $student2advancedgradingdata; $grades[] = $student2gradeinfo; $result = mod_assign_external::save_grades($instance->id, false, $grades); // No warnings. $this->assertEquals(0, count($result)); $student1grade = $DB->get_record('assign_grades', array('userid' => $student1->id, 'assignment' => $instance->id), '*', MUST_EXIST); $this->assertEquals($student1grade->grade, '50.0'); $student2grade = $DB->get_record('assign_grades', array('userid' => $student2->id, 'assignment' => $instance->id), '*', MUST_EXIST); $this->assertEquals($student2grade->grade, '100.0'); } /** * Test save grades for a team submission */ public function test_save_grades_with_group_submission() { global $DB, $USER, $CFG; require_once($CFG->dirroot . '/group/lib.php'); $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $groupingdata = array(); $groupingdata['courseid'] = $course->id; $groupingdata['name'] = 'Group assignment grouping'; $grouping = self::getDataGenerator()->create_grouping($groupingdata); $group1data = array(); $group1data['courseid'] = $course->id; $group1data['name'] = 'Team 1'; $group2data = array(); $group2data['courseid'] = $course->id; $group2data['name'] = 'Team 2'; $group1 = self::getDataGenerator()->create_group($group1data); $group2 = self::getDataGenerator()->create_group($group2data); groups_assign_grouping($grouping->id, $group1->id); groups_assign_grouping($grouping->id, $group2->id); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['teamsubmission'] = 1; $params['teamsubmissiongroupingid'] = $grouping->id; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $student2 = self::getDataGenerator()->create_user(); $student3 = self::getDataGenerator()->create_user(); $student4 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id); $this->getDataGenerator()->enrol_user($student4->id, $course->id, $studentrole->id); groups_add_member($group1->id, $student1->id); groups_add_member($group1->id, $student2->id); groups_add_member($group1->id, $student3->id); groups_add_member($group2->id, $student4->id); $this->setUser($teacher); $feedbackpluginparams = array(); $feedbackpluginparams['files_filemanager'] = 0; $feedbackeditorparams = array('text' => '', 'format' => 1); $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; $grades1 = array(); $student1gradeinfo = array(); $student1gradeinfo['userid'] = $student1->id; $student1gradeinfo['grade'] = 50; $student1gradeinfo['attemptnumber'] = -1; $student1gradeinfo['addattempt'] = true; $student1gradeinfo['workflowstate'] = 'released'; $student1gradeinfo['plugindata'] = $feedbackpluginparams; $grades1[] = $student1gradeinfo; $student2gradeinfo = array(); $student2gradeinfo['userid'] = $student2->id; $student2gradeinfo['grade'] = 75; $student2gradeinfo['attemptnumber'] = -1; $student2gradeinfo['addattempt'] = true; $student2gradeinfo['workflowstate'] = 'released'; $student2gradeinfo['plugindata'] = $feedbackpluginparams; $grades1[] = $student2gradeinfo; $this->setExpectedException('invalid_parameter_exception'); // Expect an exception since 2 grades have been submitted for the same team. $result = mod_assign_external::save_grades($instance->id, true, $grades1); $grades2 = array(); $student3gradeinfo = array(); $student3gradeinfo['userid'] = $student3->id; $student3gradeinfo['grade'] = 50; $student3gradeinfo['attemptnumber'] = -1; $student3gradeinfo['addattempt'] = true; $student3gradeinfo['workflowstate'] = 'released'; $student3gradeinfo['plugindata'] = $feedbackpluginparams; $grades2[] = $student3gradeinfo; $student4gradeinfo = array(); $student4gradeinfo['userid'] = $student4->id; $student4gradeinfo['grade'] = 75; $student4gradeinfo['attemptnumber'] = -1; $student4gradeinfo['addattempt'] = true; $student4gradeinfo['workflowstate'] = 'released'; $student4gradeinfo['plugindata'] = $feedbackpluginparams; $grades2[] = $student4gradeinfo; $result = mod_assign_external::save_grades($instance->id, true, $grades2); // There should be no warnings. $this->assertEquals(0, count($result)); $student3grade = $DB->get_record('assign_grades', array('userid' => $student3->id, 'assignment' => $instance->id), '*', MUST_EXIST); $this->assertEquals($student3grade->grade, '50.0'); $student4grade = $DB->get_record('assign_grades', array('userid' => $student4->id, 'assignment' => $instance->id), '*', MUST_EXIST); $this->assertEquals($student4grade->grade, '75.0'); } /** * Test copy_previous_attempt */ public function test_copy_previous_attempt() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment and users. $course = self::getDataGenerator()->create_course(); $teacher = self::getDataGenerator()->create_user(); $teacherrole = $DB->get_record('role', array('shortname'=>'teacher')); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); $this->setUser($teacher); $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); $params['course'] = $course->id; $params['assignsubmission_onlinetext_enabled'] = 1; $params['assignsubmission_file_enabled'] = 0; $params['assignfeedback_file_enabled'] = 0; $params['attemptreopenmethod'] = 'manual'; $params['maxattempts'] = 5; $instance = $generator->create_instance($params); $cm = get_coursemodule_from_instance('assign', $instance->id); $context = context_module::instance($cm->id); $assign = new assign($context, $cm, $course); $student1 = self::getDataGenerator()->create_user(); $studentrole = $DB->get_record('role', array('shortname'=>'student')); $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); // Now try a submission. $this->setUser($student1); $draftidonlinetext = file_get_unused_draft_itemid(); $submissionpluginparams = array(); $onlinetexteditorparams = array('text'=>'Yeeha!', 'format'=>1, 'itemid'=>$draftidonlinetext); $submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams; $submissionpluginparams['files_filemanager'] = file_get_unused_draft_itemid(); $result = mod_assign_external::save_submission($instance->id, $submissionpluginparams); $this->setUser($teacher); // Add a grade and reopen the attempt. // Now try a grade. $feedbackpluginparams = array(); $feedbackpluginparams['files_filemanager'] = file_get_unused_draft_itemid(); $feedbackeditorparams = array('text'=>'Yeeha!', 'format'=>1); $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams; $result = mod_assign_external::save_grade($instance->id, $student1->id, 50.0, -1, true, 'released', false, $feedbackpluginparams); $this->setUser($student1); // Now copy the previous attempt. $result = mod_assign_external::copy_previous_attempt($instance->id); // No warnings. $this->assertEquals(0, count($result)); $this->setUser($teacher); $result = mod_assign_external::get_submissions(array($instance->id)); // Check we are now on the second attempt. $this->assertEquals($result['assignments'][0]['submissions'][0]['attemptnumber'], 1); // Check the plugins data is not empty. $this->assertNotEmpty($result['assignments'][0]['submissions'][0]['plugins']); } /** * Test set_user_flags */ public function test_set_user_flags() { global $DB, $USER; $this->resetAfterTest(true); // Create a course and assignment. $coursedata['idnumber'] = 'idnumbercourse'; $coursedata['fullname'] = 'Lightwork Course'; $coursedata['summary'] = 'Lightwork Course description'; $coursedata['summaryformat'] = FORMAT_MOODLE; $course = self::getDataGenerator()->create_course($coursedata); $assigndata['course'] = $course->id; $assigndata['name'] = 'lightwork assignment'; $assign = self::getDataGenerator()->create_module('assign', $assigndata); // Create a manual enrolment record. $manualenroldata['enrol'] = 'manual'; $manualenroldata['status'] = 0; $manualenroldata['courseid'] = $course->id; $enrolid = $DB->insert_record('enrol', $manualenroldata); // Create a teacher and give them capabilities. $context = context_course::instance($course->id); $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3); $context = context_module::instance($assign->cmid); $this->assignUserCapability('mod/assign:grade', $context->id, $roleid); // Create the teacher's enrolment record. $userenrolmentdata['status'] = 0; $userenrolmentdata['enrolid'] = $enrolid; $userenrolmentdata['userid'] = $USER->id; $DB->insert_record('user_enrolments', $userenrolmentdata); // Create a student. $student = self::getDataGenerator()->create_user(); // Create test user flags record. $userflags = array(); $userflag['userid'] = $student->id; $userflag['workflowstate'] = 'inmarking'; $userflag['allocatedmarker'] = $USER->id; $userflags = array($userflag); $createduserflags = mod_assign_external::set_user_flags($assign->id, $userflags); // We need to execute the return values cleaning process to simulate the web service server. $createduserflags = external_api::clean_returnvalue(mod_assign_external::set_user_flags_returns(), $createduserflags); $this->assertEquals($student->id, $createduserflags[0]['userid']); $createduserflag = $DB->get_record('assign_user_flags', array('id' => $createduserflags[0]['id'])); // Confirm that all data was inserted correctly. $this->assertEquals($student->id, $createduserflag->userid); $this->assertEquals($assign->id, $createduserflag->assignment); $this->assertEquals(0, $createduserflag->locked); $this->assertEquals(2, $createduserflag->mailed); $this->assertEquals(0, $createduserflag->extensionduedate); $this->assertEquals('inmarking', $createduserflag->workflowstate); $this->assertEquals($USER->id, $createduserflag->allocatedmarker); // Create update data. $userflags = array(); $userflag['userid'] = $createduserflag->userid; $userflag['workflowstate'] = 'readyforreview'; $userflags = array($userflag); $updateduserflags = mod_assign_external::set_user_flags($assign->id, $userflags); // We need to execute the return values cleaning process to simulate the web service server. $updateduserflags = external_api::clean_returnvalue(mod_assign_external::set_user_flags_returns(), $updateduserflags); $this->assertEquals($student->id, $updateduserflags[0]['userid']); $updateduserflag = $DB->get_record('assign_user_flags', array('id' => $updateduserflags[0]['id'])); // Confirm that all data was updated correctly. $this->assertEquals($student->id, $updateduserflag->userid); $this->assertEquals($assign->id, $updateduserflag->assignment); $this->assertEquals(0, $updateduserflag->locked); $this->assertEquals(2, $updateduserflag->mailed); $this->assertEquals(0, $updateduserflag->extensionduedate); $this->assertEquals('readyforreview', $updateduserflag->workflowstate); $this->assertEquals($USER->id, $updateduserflag->allocatedmarker); } }