This commit is contained in:
Jun Pataleta 2022-05-03 22:22:39 +08:00
commit b625dabb83
2 changed files with 72 additions and 5 deletions

View File

@ -543,7 +543,7 @@ class quiz {
$qcategories = array();
foreach ($this->get_questions() as $questiondata) {
if ($questiondata->qtype == 'random' and $includepotential) {
if ($questiondata->qtype === 'random' && $includepotential) {
if (!isset($qcategories[$questiondata->category])) {
$qcategories[$questiondata->category] = false;
}
@ -1648,7 +1648,7 @@ class quiz_attempt {
* @return bool whether show all on one page should be on by default.
*/
public function get_default_show_all($script) {
return $script == 'review' && count($this->questionpages) < self::MAX_SLOTS_FOR_DEFAULT_REVIEW_SHOW_ALL;
return $script === 'review' && count($this->questionpages) < self::MAX_SLOTS_FOR_DEFAULT_REVIEW_SHOW_ALL;
}
// Bits of content =========================================================
@ -2409,7 +2409,7 @@ class quiz_attempt {
$becomingoverdue = false;
$becomingabandoned = false;
if ($timeup) {
if ($this->get_quiz()->overduehandling == 'graceperiod') {
if ($this->get_quiz()->overduehandling === 'graceperiod') {
if (is_null($graceperiodmin)) {
$graceperiodmin = get_config('quiz', 'graceperiodmin');
}
@ -2469,7 +2469,15 @@ class quiz_attempt {
if ($becomingabandoned) {
$this->process_abandon($timenow, true);
} else {
$this->process_finish($timenow, !$toolate, $toolate ? $timeclose : $timenow, true);
if (!$toolate || $this->get_quiz()->overduehandling === 'graceperiod') {
// Normally, we record the accurate finish time when the student is online.
$finishtime = $timenow;
} else {
// But, if there is no grade period, and the final responses were too
// late to be processed, record the close time, to reduce confusion.
$finishtime = $timeclose;
}
$this->process_finish($timenow, !$toolate, $finishtime, true);
}
} catch (question_out_of_sequence_exception $e) {
@ -2795,7 +2803,7 @@ abstract class quiz_nav_panel_base {
$button->number = $this->attemptobj->get_question_number($slot);
$button->stateclass = $qa->get_state_class($showcorrectness);
$button->navmethod = $this->attemptobj->get_navigation_method();
if (!$showcorrectness && $button->stateclass == 'notanswered') {
if (!$showcorrectness && $button->stateclass === 'notanswered') {
$button->stateclass = 'complete';
}
$button->statestring = $this->get_state_string($qa, $showcorrectness);

View File

@ -119,6 +119,65 @@ class mod_quiz_attempt_walkthrough_testcase extends advanced_testcase {
$this->assertEquals(100, $gradebookgrade->grade);
}
public function test_quiz_attempt_walkthrough_submit_time_recorded_correctly_when_overdue() {
global $SITE;
$this->resetAfterTest();
// Make a quiz.
$timeclose = time() + HOURSECS;
$quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
$quiz = $quizgenerator->create_instance(
['course' => $SITE->id, 'timeclose' => $timeclose,
'overduehandling' => 'graceperiod', 'graceperiod' => HOURSECS]);
// Create a question.
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
$cat = $questiongenerator->create_question_category();
$saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
// Add them to the quiz.
quiz_add_quiz_question($saq->id, $quiz, 0, 1);
quiz_update_sumgrades($quiz);
// Make a user to do the quiz.
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$quizobj = quiz::create($quiz->id, $user->id);
// Start the attempt.
$attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null);
// Process some responses from the student.
$attemptobj = quiz_attempt::create($attempt->id);
$attemptobj->process_submitted_actions($timeclose - 30 * MINSECS, false, [1 => ['answer' => 'frog']]);
// Attempt goes overdue (e.g. if cron ran).
$attemptobj = quiz_attempt::create($attempt->id);
$attemptobj->process_going_overdue($timeclose + 2 * get_config('quiz', 'graceperiodmin'), false);
// Verify the attempt state.
$attemptobj = quiz_attempt::create($attempt->id);
$this->assertEquals(1, $attemptobj->get_attempt_number());
$this->assertEquals(false, $attemptobj->is_finished());
$this->assertEquals(0, $attemptobj->get_submitted_date());
$this->assertEquals($user->id, $attemptobj->get_userid());
$this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
// Student submits the attempt during the grace period.
$attemptobj = quiz_attempt::create($attempt->id);
$attemptobj->process_attempt($timeclose + 30 * MINSECS, true, false, 1);
// Verify the attempt state.
$attemptobj = quiz_attempt::create($attempt->id);
$this->assertEquals(1, $attemptobj->get_attempt_number());
$this->assertEquals(true, $attemptobj->is_finished());
$this->assertEquals($timeclose + 30 * MINSECS, $attemptobj->get_submitted_date());
$this->assertEquals($user->id, $attemptobj->get_userid());
$this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
}
/**
* Create a quiz with a random as well as other questions and walk through quiz attempts.
*/