public function test_quiz_report_overview_report_forcesubmit_specific_attempt()
 {
     global $DB;
     $this->resetAfterTest();
     $generator = $this->getDataGenerator();
     $quizgenerator = $generator->get_plugin_generator('mod_quiz');
     $questiongenerator = $generator->get_plugin_generator('core_question');
     // Make a user to do the quiz.
     $user1 = $generator->create_user();
     $user2 = $generator->create_user();
     $user3 = $generator->create_user();
     // Create our course.
     $course = $generator->create_course(array('visible' => true));
     // Create the quiz.
     $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'visible' => true, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2));
     // Create two questions.
     $cat = $questiongenerator->create_question_category();
     $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
     $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     // Add the questions to the quiz.
     quiz_add_quiz_question($saq->id, $quiz);
     quiz_add_quiz_question($numq->id, $quiz);
     // Get a quiz object with user access overrides.
     $quizobj = quiz::create($quiz->id, $user1->id);
     $quizobj2 = quiz::create($quiz->id, $user2->id);
     $quizobj3 = quiz::create($quiz->id, $user3->id);
     // Start the attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $quba2 = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2->get_context());
     $quba2->set_preferred_behaviour($quizobj2->get_quiz()->preferredbehaviour);
     $quba3 = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj3->get_context());
     $quba3->set_preferred_behaviour($quizobj3->get_quiz()->preferredbehaviour);
     // Create a quiz attempt.
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $user1->id);
     $attempt2 = quiz_create_attempt($quizobj2, 1, false, $timenow, false, $user2->id);
     $attempt3 = quiz_create_attempt($quizobj3, 1, false, $timenow, false, $user3->id);
     // Start the attempt.
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     quiz_start_new_attempt($quizobj2, $quba2, $attempt2, 1, $timenow);
     quiz_attempt_save_started($quizobj2, $quba2, $attempt2);
     quiz_start_new_attempt($quizobj3, $quba3, $attempt3, 1, $timenow);
     quiz_attempt_save_started($quizobj3, $quba3, $attempt3);
     // Answer first question and set it overdue.
     $tosubmit = array(1 => array('answer' => 'frog'));
     $tosubmit2 = array(1 => array('answer' => 'tiger'));
     $tosubmit3 = array(1 => array('answer' => 'tiger'));
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_submitted_actions($timenow, true, $tosubmit);
     $attemptobj2 = quiz_attempt::create($attempt2->id);
     $attemptobj2->process_submitted_actions($timenow, true, $tosubmit2);
     $attemptobj3 = quiz_attempt::create($attempt3->id);
     $attemptobj3->process_submitted_actions($timenow, true, $tosubmit3);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_abandon($timenow, false);
     // Re-load quiz attempt2 data.
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj2 = quiz_attempt::create($attempt2->id);
     $attemptobj3 = quiz_attempt::create($attempt3->id);
     // Check that the state of the attempt is as expected.
     $this->assertEquals(1, $attemptobj->get_attempt_number());
     $this->assertEquals(quiz_attempt::ABANDONED, $attemptobj->get_state());
     $this->assertEquals($user1->id, $attemptobj->get_userid());
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     // Check that the state of the attempt2 is as expected.
     $this->assertEquals(1, $attemptobj2->get_attempt_number());
     $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj2->get_state());
     $this->assertEquals($user2->id, $attemptobj2->get_userid());
     $this->assertTrue($attemptobj2->has_response_to_at_least_one_graded_question());
     // Check that the state of the attempt3 is as expected.
     $this->assertEquals(1, $attemptobj3->get_attempt_number());
     $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj3->get_state());
     $this->assertEquals($user3->id, $attemptobj3->get_userid());
     $this->assertTrue($attemptobj3->has_response_to_at_least_one_graded_question());
     // Force submit the attempts.
     $overviewreport = new quiz_overview_report_testable();
     $overviewreport->forcesubmit_attempts($quiz, false, array(), array($attempt->id, $attempt3->id));
     // Check that it is now finished.
     $attemptobj = quiz_attempt::create($attempt->id);
     $this->assertEquals(quiz_attempt::FINISHED, $attemptobj->get_state());
     $attemptobj2 = quiz_attempt::create($attempt2->id);
     $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj2->get_state());
     $attemptobj3 = quiz_attempt::create($attempt3->id);
     $this->assertEquals(quiz_attempt::FINISHED, $attemptobj3->get_state());
 }
Пример #2
0
 protected function prepare_quiz_data()
 {
     $this->resetAfterTest(true);
     // Create a course
     $course = $this->getDataGenerator()->create_course();
     // Make a quiz.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2));
     $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id);
     // Create a couple of questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
     $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     // Add them to the quiz.
     quiz_add_quiz_question($saq->id, $quiz);
     quiz_add_quiz_question($numq->id, $quiz);
     // Make a user to do the quiz.
     $user1 = $this->getDataGenerator()->create_user();
     $this->setUser($user1);
     $quizobj = quiz::create($quiz->id, $user1->id);
     // Start the attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     return array($quizobj, $quba, $attempt);
 }
Пример #3
0
 public function test_quiz_get_user_attempts()
 {
     global $DB;
     $this->resetAfterTest();
     $dg = $this->getDataGenerator();
     $quizgen = $dg->get_plugin_generator('mod_quiz');
     $course = $dg->create_course();
     $u1 = $dg->create_user();
     $u2 = $dg->create_user();
     $u3 = $dg->create_user();
     $u4 = $dg->create_user();
     $role = $DB->get_record('role', ['shortname' => 'student']);
     $dg->enrol_user($u1->id, $course->id, $role->id);
     $dg->enrol_user($u2->id, $course->id, $role->id);
     $dg->enrol_user($u3->id, $course->id, $role->id);
     $dg->enrol_user($u4->id, $course->id, $role->id);
     $quiz1 = $quizgen->create_instance(['course' => $course->id, 'sumgrades' => 2]);
     $quiz2 = $quizgen->create_instance(['course' => $course->id, 'sumgrades' => 2]);
     // Questions.
     $questgen = $dg->get_plugin_generator('core_question');
     $quizcat = $questgen->create_question_category();
     $question = $questgen->create_question('numerical', null, ['category' => $quizcat->id]);
     quiz_add_quiz_question($question->id, $quiz1);
     quiz_add_quiz_question($question->id, $quiz2);
     $quizobj1a = quiz::create($quiz1->id, $u1->id);
     $quizobj1b = quiz::create($quiz1->id, $u2->id);
     $quizobj1c = quiz::create($quiz1->id, $u3->id);
     $quizobj1d = quiz::create($quiz1->id, $u4->id);
     $quizobj2a = quiz::create($quiz2->id, $u1->id);
     // Set attempts.
     $quba1a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1a->get_context());
     $quba1a->set_preferred_behaviour($quizobj1a->get_quiz()->preferredbehaviour);
     $quba1b = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1b->get_context());
     $quba1b->set_preferred_behaviour($quizobj1b->get_quiz()->preferredbehaviour);
     $quba1c = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1c->get_context());
     $quba1c->set_preferred_behaviour($quizobj1c->get_quiz()->preferredbehaviour);
     $quba1d = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1d->get_context());
     $quba1d->set_preferred_behaviour($quizobj1d->get_quiz()->preferredbehaviour);
     $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context());
     $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour);
     $timenow = time();
     // User 1 passes quiz 1.
     $attempt = quiz_create_attempt($quizobj1a, 1, false, $timenow, false, $u1->id);
     quiz_start_new_attempt($quizobj1a, $quba1a, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj1a, $quba1a, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_submitted_actions($timenow, false, [1 => ['answer' => '3.14']]);
     $attemptobj->process_finish($timenow, false);
     // User 2 goes overdue in quiz 1.
     $attempt = quiz_create_attempt($quizobj1b, 1, false, $timenow, false, $u2->id);
     quiz_start_new_attempt($quizobj1b, $quba1b, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj1b, $quba1b, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_going_overdue($timenow, true);
     // User 3 does not finish quiz 1.
     $attempt = quiz_create_attempt($quizobj1c, 1, false, $timenow, false, $u3->id);
     quiz_start_new_attempt($quizobj1c, $quba1c, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj1c, $quba1c, $attempt);
     // User 4 abandons the quiz 1.
     $attempt = quiz_create_attempt($quizobj1d, 1, false, $timenow, false, $u4->id);
     quiz_start_new_attempt($quizobj1d, $quba1d, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj1d, $quba1d, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_abandon($timenow, true);
     // User 1 attempts the quiz three times (abandon, finish, in progress).
     $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context());
     $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour);
     $attempt = quiz_create_attempt($quizobj2a, 1, false, $timenow, false, $u1->id);
     quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj2a, $quba2a, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_abandon($timenow, true);
     $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context());
     $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour);
     $attempt = quiz_create_attempt($quizobj2a, 2, false, $timenow, false, $u1->id);
     quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 2, $timenow);
     quiz_attempt_save_started($quizobj2a, $quba2a, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_finish($timenow, false);
     $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context());
     $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour);
     $attempt = quiz_create_attempt($quizobj2a, 3, false, $timenow, false, $u1->id);
     quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 3, $timenow);
     quiz_attempt_save_started($quizobj2a, $quba2a, $attempt);
     // Check for user 1.
     $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'all');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'finished');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'unfinished');
     $this->assertCount(0, $attempts);
     // Check for user 2.
     $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'all');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::OVERDUE, $attempt->state);
     $this->assertEquals($u2->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'finished');
     $this->assertCount(0, $attempts);
     $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'unfinished');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::OVERDUE, $attempt->state);
     $this->assertEquals($u2->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     // Check for user 3.
     $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'all');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state);
     $this->assertEquals($u3->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'finished');
     $this->assertCount(0, $attempts);
     $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'unfinished');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state);
     $this->assertEquals($u3->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     // Check for user 4.
     $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'all');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state);
     $this->assertEquals($u4->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'finished');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state);
     $this->assertEquals($u4->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'unfinished');
     $this->assertCount(0, $attempts);
     // Multiple attempts for user 1 in quiz 2.
     $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'all');
     $this->assertCount(3, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
     $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'finished');
     $this->assertCount(2, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'unfinished');
     $this->assertCount(1, $attempts);
     $attempt = array_shift($attempts);
     // Multiple quiz attempts fetched at once.
     $attempts = quiz_get_user_attempts([$quiz1->id, $quiz2->id], $u1->id, 'all');
     $this->assertCount(4, $attempts);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz1->id, $attempt->quiz);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::FINISHED, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
     $attempt = array_shift($attempts);
     $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state);
     $this->assertEquals($u1->id, $attempt->userid);
     $this->assertEquals($quiz2->id, $attempt->quiz);
 }
                $PAGE->blocks->show_only_fake_blocks();
            }
            echo $output->start_attempt_page($quizobj, $mform);
            die;
        }
    }
    // Pre-flight check passed.
    $accessmanager->notify_preflight_check_passed($currentattemptid);
}
if ($currentattemptid) {
    redirect($quizobj->attempt_url($currentattemptid, $page));
}
// Delete any previous preview attempts belonging to this user.
quiz_delete_previews($quizobj->get_quiz(), $USER->id);
$quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
$quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
// Create the new attempt and initialize the question sessions
$timenow = time();
// Update time now, in case the server is running really slowly.
$attempt = quiz_create_attempt($quizobj, $attemptnumber, $lastattempt, $timenow, $quizobj->is_preview_user());
if (!($quizobj->get_quiz()->attemptonlast && $lastattempt)) {
    $attempt = quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow);
} else {
    $attempt = quiz_start_attempt_built_on_last($quba, $attempt, $lastattempt);
}
$transaction = $DB->start_delegated_transaction();
$attempt = quiz_attempt_save_started($quizobj, $quba, $attempt);
quiz_fire_attempt_started_event($attempt, $quizobj);
$transaction->allow_commit();
// Redirect to the attempt page.
redirect($quizobj->attempt_url($attempt->id, $page));
Пример #5
0
 /**
  * Test get_attempt_access_information
  */
 public function test_get_attempt_access_information()
 {
     global $DB;
     // Create a new quiz with attempts.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $this->course->id, 'sumgrades' => 2);
     $quiz = $quizgenerator->create_instance($data);
     // Create some questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     $question = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     // Add new question types in the category (for the random one).
     $question = $questiongenerator->create_question('truefalse', null, array('category' => $cat->id));
     $question = $questiongenerator->create_question('essay', null, array('category' => $cat->id));
     $question = $questiongenerator->create_question('random', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     $quizobj = quiz::create($quiz->id, $this->student->id);
     // Set grade to pass.
     $item = grade_item::fetch(array('courseid' => $this->course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
     $item->gradepass = 80;
     $item->update();
     $this->setUser($this->student);
     // Default restrictions (none).
     $result = mod_quiz_external::get_attempt_access_information($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_attempt_access_information_returns(), $result);
     $expected = array('isfinished' => false, 'preventnewattemptreasons' => [], 'warnings' => []);
     $this->assertEquals($expected, $result);
     // Limited attempts.
     $quiz->attempts = 1;
     $DB->update_record('quiz', $quiz);
     // Now, do one attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $this->student->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     // Process some responses from the student.
     $attemptobj = quiz_attempt::create($attempt->id);
     $tosubmit = array(1 => array('answer' => '3.14'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_finish($timenow, false);
     // Can we start a new attempt? We shall not!
     $result = mod_quiz_external::get_attempt_access_information($quiz->id, $attempt->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_attempt_access_information_returns(), $result);
     // Now new attemps allowed.
     $this->assertCount(1, $result['preventnewattemptreasons']);
     $this->assertFalse($result['ispreflightcheckrequired']);
     $this->assertEquals(get_string('nomoreattempts', 'quiz'), $result['preventnewattemptreasons'][0]);
 }
 /**
  * This function is a copy of code taken from attempt_walkthrough_test.php
  * that creates a sample quiz and has a student complete the quiz.
  *
  * If the test suddenly stops working, grab the new code from that file, then
  * adjust to required inputs/outputs.
  *
  * @param object $course The course object to create the quiz in
  * @param object $student The student object that takes the quiz
  * @return array {attempt ID (int), quiz ID (int)}
  *
  */
 private function create_quiz_attempt($course, $student)
 {
     // Make a quiz.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2));
     // Create a couple of questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
     $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     // Add them to the quiz.
     quiz_add_quiz_question($saq->id, $quiz);
     quiz_add_quiz_question($numq->id, $quiz);
     $quizobj = quiz::create($quiz->id, $student->id);
     // Start the attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $student->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     // Process some responses from the student.
     $attemptobj = quiz_attempt::create($attempt->id);
     $prefix1 = $quba->get_field_prefix(1);
     $prefix2 = $quba->get_field_prefix(2);
     $tosubmit = array(1 => array('answer' => 'frog'), 2 => array('answer' => '3.14'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_finish($timenow, false);
     // Re-load quiz attempt data.
     $attemptobj = quiz_attempt::create($attempt->id);
     return array($attempt->id, $quiz->id);
 }
Пример #7
0
 /**
  * Test checking the completion state of a quiz.
  */
 public function test_quiz_get_completion_state()
 {
     global $CFG, $DB;
     $this->resetAfterTest(true);
     // Enable completion before creating modules, otherwise the completion data is not written in DB.
     $CFG->enablecompletion = true;
     // Create a course and student.
     $course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
     $passstudent = $this->getDataGenerator()->create_user();
     $failstudent = $this->getDataGenerator()->create_user();
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     $this->assertNotEmpty($studentrole);
     // Enrol students.
     $this->assertTrue($this->getDataGenerator()->enrol_user($passstudent->id, $course->id, $studentrole->id));
     $this->assertTrue($this->getDataGenerator()->enrol_user($failstudent->id, $course->id, $studentrole->id));
     // Make a scale and an outcome.
     $scale = $this->getDataGenerator()->create_scale();
     $data = array('courseid' => $course->id, 'fullname' => 'Team work', 'shortname' => 'Team work', 'scaleid' => $scale->id);
     $outcome = $this->getDataGenerator()->create_grade_outcome($data);
     // Make a quiz with the outcome on.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $course->id, 'outcome_' . $outcome->id => 1, 'grade' => 100.0, 'questionsperpage' => 0, 'sumgrades' => 1, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionpass' => 1);
     $quiz = $quizgenerator->create_instance($data);
     $cm = get_coursemodule_from_id('quiz', $quiz->cmid);
     // Create a couple of questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     $quizobj = quiz::create($quiz->id, $passstudent->id);
     // Set grade to pass.
     $item = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
     $item->gradepass = 80;
     $item->update();
     // Start the passing attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $passstudent->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     // Process some responses from the student.
     $attemptobj = quiz_attempt::create($attempt->id);
     $tosubmit = array(1 => array('answer' => '3.14'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_finish($timenow, false);
     // Start the failing attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $failstudent->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     // Process some responses from the student.
     $attemptobj = quiz_attempt::create($attempt->id);
     $tosubmit = array(1 => array('answer' => '0'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_finish($timenow, false);
     // Check the results.
     $this->assertTrue(quiz_get_completion_state($course, $cm, $passstudent->id, 'return'));
     $this->assertFalse(quiz_get_completion_state($course, $cm, $failstudent->id, 'return'));
 }
Пример #8
0
/**
 * Prepare and start a new attempt deleting the previous preview attempts.
 *
 * @param  quiz $quizobj quiz object
 * @param  int $attemptnumber the attempt number
 * @param  object $lastattempt last attempt object
 * @param bool $offlineattempt whether is an offline attempt or not
 * @return object the new attempt
 * @since  Moodle 3.1
 */
function quiz_prepare_and_start_new_attempt(quiz $quizobj, $attemptnumber, $lastattempt, $offlineattempt = false)
{
    global $DB, $USER;
    // Delete any previous preview attempts belonging to this user.
    quiz_delete_previews($quizobj->get_quiz(), $USER->id);
    $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
    $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
    // Create the new attempt and initialize the question sessions
    $timenow = time();
    // Update time now, in case the server is running really slowly.
    $attempt = quiz_create_attempt($quizobj, $attemptnumber, $lastattempt, $timenow, $quizobj->is_preview_user());
    if (!($quizobj->get_quiz()->attemptonlast && $lastattempt)) {
        $attempt = quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow);
    } else {
        $attempt = quiz_start_attempt_built_on_last($quba, $attempt, $lastattempt);
    }
    $transaction = $DB->start_delegated_transaction();
    // Init the timemodifiedoffline for offline attempts.
    if ($offlineattempt) {
        $attempt->timemodifiedoffline = $attempt->timemodified;
    }
    $attempt = quiz_attempt_save_started($quizobj, $quba, $attempt);
    $transaction->allow_commit();
    return $attempt;
}
Пример #9
0
 /**
  * Test the attempt previewed event.
  */
 public function test_attempt_preview_started()
 {
     list($quizobj, $quba, $attempt) = $this->prepare_quiz_data();
     // We want to preview this attempt.
     $attempt = quiz_create_attempt($quizobj, 1, false, time(), false, 2);
     $attempt->preview = 1;
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     $events = $sink->get_events();
     $event = reset($events);
     // Check that the event data is valid.
     $this->assertInstanceOf('\\mod_quiz\\event\\attempt_preview_started', $event);
     $this->assertEquals(context_module::instance($quizobj->get_cmid()), $event->get_context());
     $expected = array($quizobj->get_courseid(), 'quiz', 'preview', 'view.php?id=' . $quizobj->get_cmid(), $quizobj->get_quizid(), $quizobj->get_cmid());
     $this->assertEventLegacyLogData($expected, $event);
     $this->assertEventContextNotUsed($event);
 }
Пример #10
0
    /**
     * Create a quiz with a single question with variants and walk through quiz attempts.
     *
     * @dataProvider get_correct_response_for_variants
     */
    public function test_quiz_with_question_with_variants_attempt_walkthrough($variantno, $correctresponse, $done = false) {
        global $SITE;

        $this->resetAfterTest($done);

        $this->setAdminUser();

        if ($this->quizwithvariants === null) {
            // Make a quiz.
            $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');

            $this->quizwithvariants = $quizgenerator->create_instance(array('course'=>$SITE->id,
                                                                            'questionsperpage' => 0,
                                                                            'grade' => 100.0,
                                                                            'sumgrades' => 1));

            $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');

            $cat = $questiongenerator->create_question_category();
            $calc = $questiongenerator->create_question('calculatedsimple', 'sumwithvariants', array('category' => $cat->id));
            quiz_add_quiz_question($calc->id, $this->quizwithvariants, 0);
        }


        // Make a new user to do the quiz.
        $user1 = $this->getDataGenerator()->create_user();
        $this->setUser($user1);
        $quizobj = quiz::create($this->quizwithvariants->id, $user1->id);

        // Start the attempt.
        $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
        $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);

        $timenow = time();
        $attempt = quiz_create_attempt($quizobj, 1, false, $timenow);

        // Select variant.
        quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow, array(), array(1 => $variantno));
        $this->assertEquals('1,0', $attempt->layout);
        quiz_attempt_save_started($quizobj, $quba, $attempt);

        // Process some responses from the student.
        $attemptobj = quiz_attempt::create($attempt->id);
        $tosubmit = array(1 => array('answer' => $correctresponse));
        $attemptobj->process_submitted_actions($timenow, false, $tosubmit);

        // Finish the attempt.
        $attemptobj = quiz_attempt::create($attempt->id);
        $attemptobj->process_finish($timenow, false);

        // Re-load quiz attempt data.
        $attemptobj = quiz_attempt::create($attempt->id);

        // Check that results are stored as expected.
        $this->assertEquals(1, $attemptobj->get_attempt_number());
        $this->assertEquals(1, $attemptobj->get_sum_marks());
        $this->assertEquals(true, $attemptobj->is_finished());
        $this->assertEquals($timenow, $attemptobj->get_submitted_date());
        $this->assertEquals($user1->id, $attemptobj->get_userid());

        // Check quiz grades.
        $grades = quiz_get_user_grades($this->quizwithvariants, $user1->id);
        $grade = array_shift($grades);
        $this->assertEquals(100.0, $grade->rawgrade);

        // Check grade book.
        $gradebookgrades = grade_get_grades($SITE->id, 'mod', 'quiz', $this->quizwithvariants->id, $user1->id);
        $gradebookitem = array_shift($gradebookgrades->items);
        $gradebookgrade = array_shift($gradebookitem->grades);
        $this->assertEquals(100, $gradebookgrade->grade);
    }
Пример #11
0
function emarking_add_user_attempt($cm, $user)
{
    global $DB;
    // Get the quiz object
    $quizobj = quiz::create($cm->instance, $user->id);
    // TODO get to know what usage by activity means
    $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
    $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
    // Create the new attempt and initialize the question sessions
    $attemptnumber = 1;
    $lastattempt = null;
    $timenow = time();
    // Update time now, in case the server is running really slowly.
    $attempt = quiz_create_attempt($quizobj, $attemptnumber, $lastattempt, $timenow, false, $user->id);
    $attempt = quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow);
    $transaction = $DB->start_delegated_transaction();
    $attempt = quiz_attempt_save_started($quizobj, $quba, $attempt);
    $DB->commit_delegated_transaction($transaction);
}
Пример #12
0
 /**
  * Utility method to submit an attempt on a quiz.
  * @param $quiz
  * @param $user
  * @param $answers
  * @return testable_assign
  */
 private function submit_quiz_attempt($quiz, $user, $answers)
 {
     // Create a quiz attempt for the user.
     $quizobj = quiz::create($quiz->id, $user->id);
     // Set up and start an attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $user->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_submitted_actions($timenow, false, $answers);
     $timefinish = time();
     // Finish the attempt.
     $attemptobj->process_finish($timefinish, false);
     return $timefinish;
 }
 /**
  * @param $steps PHPUnit_Extensions_Database_DataSet_ITable the step data from the csv file.
  * @return array attempt no as in csv file => the id of the quiz_attempt as stored in the db.
  */
 protected function walkthrough_attempts($steps)
 {
     global $DB;
     $attemptids = array();
     for ($rowno = 0; $rowno < $steps->getRowCount(); $rowno++) {
         $step = $this->explode_dot_separated_keys_to_make_subindexs($steps->getRow($rowno));
         // Find existing user or make a new user to do the quiz.
         $username = array('firstname' => $step['firstname'], 'lastname' => $step['lastname']);
         if (!($user = $DB->get_record('user', $username))) {
             $user = $this->getDataGenerator()->create_user($username);
         }
         if (!isset($attemptids[$step['quizattempt']])) {
             // Start the attempt.
             $quizobj = quiz::create($this->quiz->id, $user->id);
             $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
             $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
             $prevattempts = quiz_get_user_attempts($this->quiz->id, $user->id, 'all', true);
             $attemptnumber = count($prevattempts) + 1;
             $timenow = time();
             $attempt = quiz_create_attempt($quizobj, $attemptnumber, false, $timenow, false, $user->id);
             // Select variant and / or random sub question.
             if (!isset($step['variants'])) {
                 $step['variants'] = array();
             }
             if (isset($step['randqs'])) {
                 // Replace 'names' with ids.
                 foreach ($step['randqs'] as $slotno => $randqname) {
                     $step['randqs'][$slotno] = $this->randqids[$slotno][$randqname];
                 }
             } else {
                 $step['randqs'] = array();
             }
             quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow, $step['randqs'], $step['variants']);
             quiz_attempt_save_started($quizobj, $quba, $attempt);
             $attemptid = $attemptids[$step['quizattempt']] = $attempt->id;
         } else {
             $attemptid = $attemptids[$step['quizattempt']];
         }
         // Process some responses from the student.
         $attemptobj = quiz_attempt::create($attemptid);
         $attemptobj->process_submitted_actions($timenow, false, $step['responses']);
         // Finish the attempt.
         if (!isset($step['finished']) || $step['finished'] == 1) {
             $attemptobj = quiz_attempt::create($attemptid);
             $attemptobj->process_finish($timenow, false);
         }
     }
     return $attemptids;
 }
Пример #14
0
 /**
  * Test get_combined_review_options.
  * This is a basic test, this is already tested in mod_quiz_display_options_testcase.
  */
 public function test_get_combined_review_options()
 {
     global $DB;
     // Create a new quiz with attempts.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $this->course->id, 'sumgrades' => 1);
     $quiz = $quizgenerator->create_instance($data);
     // Create a couple of questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     $quizobj = quiz::create($quiz->id, $this->student->id);
     // Set grade to pass.
     $item = grade_item::fetch(array('courseid' => $this->course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
     $item->gradepass = 80;
     $item->update();
     // Start the passing attempt.
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $this->student->id);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     $this->setUser($this->student);
     $result = mod_quiz_external::get_combined_review_options($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
     // Expected values.
     $expected = array("someoptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 0), array("name" => "marks", "value" => 2)), "alloptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 0), array("name" => "marks", "value" => 2)), "warnings" => []);
     $this->assertEquals($expected, $result);
     // Now, finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_finish($timenow, false);
     $expected = array("someoptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 1), array("name" => "marks", "value" => 2)), "alloptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 1), array("name" => "marks", "value" => 2)), "warnings" => []);
     // We should see now the overall feedback.
     $result = mod_quiz_external::get_combined_review_options($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
     $this->assertEquals($expected, $result);
     // Start a new attempt, but not finish it.
     $timenow = time();
     $attempt = quiz_create_attempt($quizobj, 2, false, $timenow, false, $this->student->id);
     $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
     $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
     quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow);
     quiz_attempt_save_started($quizobj, $quba, $attempt);
     $expected = array("someoptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 1), array("name" => "marks", "value" => 2)), "alloptions" => array(array("name" => "feedback", "value" => 1), array("name" => "generalfeedback", "value" => 1), array("name" => "rightanswer", "value" => 1), array("name" => "overallfeedback", "value" => 0), array("name" => "marks", "value" => 2)), "warnings" => []);
     $result = mod_quiz_external::get_combined_review_options($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
     $this->assertEquals($expected, $result);
     // Teacher, for see student options.
     $this->setUser($this->teacher);
     $result = mod_quiz_external::get_combined_review_options($quiz->id, $this->student->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_combined_review_options_returns(), $result);
     $this->assertEquals($expected, $result);
     // Invalid user.
     try {
         mod_quiz_external::get_combined_review_options($quiz->id, -1);
         $this->fail('Exception expected due to missing capability.');
     } catch (dml_missing_record_exception $e) {
         $this->assertEquals('invaliduser', $e->errorcode);
     }
 }