mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
MDL-43733 use any auto-saved responses when questions are finished.
Before this, autosave was only working to save data when a student went back in to continue an attempt. If the student, having crashed out, never went back in and continued the attempt, their auto-saved responses were not used when the attempt was automatically finished. That was a rather bad oversight, which should now be fixed.
This commit is contained in:
parent
f05e25d208
commit
3d96b4945a
2 changed files with 76 additions and 0 deletions
|
@ -869,6 +869,24 @@ class question_attempt {
|
||||||
$this->observer->notify_step_deleted($autosaved, $this);
|
$this->observer->notify_step_deleted($autosaved, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is an autosaved step, convert it into a real save, so that it
|
||||||
|
* is preserved.
|
||||||
|
*/
|
||||||
|
protected function convert_autosaved_step_to_real_step() {
|
||||||
|
if ($this->autosavedstep === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$laststep = end($this->steps);
|
||||||
|
if ($laststep !== $this->autosavedstep) {
|
||||||
|
throw new coding_exception('Cannot convert autosaved step to real step, since other steps have been added.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->observer->notify_step_modified($this->autosavedstep, $this, key($this->steps));
|
||||||
|
$this->autosavedstep = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a strategy to pick a variant.
|
* Use a strategy to pick a variant.
|
||||||
* @param question_variant_selection_strategy $variantstrategy a strategy.
|
* @param question_variant_selection_strategy $variantstrategy a strategy.
|
||||||
|
@ -1174,6 +1192,7 @@ class question_attempt {
|
||||||
* @param int $userid the user to attribute the aciton to. (If not given, use the current user.)
|
* @param int $userid the user to attribute the aciton to. (If not given, use the current user.)
|
||||||
*/
|
*/
|
||||||
public function finish($timestamp = null, $userid = null) {
|
public function finish($timestamp = null, $userid = null) {
|
||||||
|
$this->convert_autosaved_step_to_real_step();
|
||||||
$this->process_action(array('-finish' => 1), $timestamp, $userid);
|
$this->process_action(array('-finish' => 1), $timestamp, $userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -628,4 +628,61 @@ class question_usage_autosave_test extends qbehaviour_walkthrough_test_base {
|
||||||
|
|
||||||
$this->delete_quba();
|
$this->delete_quba();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_finish_with_unhandled_autosave_data() {
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||||
|
$cat = $generator->create_question_category();
|
||||||
|
$question = $generator->create_question('shortanswer', null,
|
||||||
|
array('category' => $cat->id));
|
||||||
|
|
||||||
|
// Start attempt at a shortanswer question.
|
||||||
|
$q = question_bank::load_question($question->id);
|
||||||
|
$this->start_attempt_at_question($q, 'deferredfeedback', 1);
|
||||||
|
|
||||||
|
$this->check_current_state(question_state::$todo);
|
||||||
|
$this->check_current_mark(null);
|
||||||
|
$this->check_step_count(1);
|
||||||
|
|
||||||
|
// Process a response and check the expected result.
|
||||||
|
$this->process_submission(array('answer' => 'cat'));
|
||||||
|
|
||||||
|
$this->check_current_state(question_state::$complete);
|
||||||
|
$this->check_current_mark(null);
|
||||||
|
$this->check_step_count(2);
|
||||||
|
$this->save_quba();
|
||||||
|
|
||||||
|
// Now check how that is re-displayed.
|
||||||
|
$this->render();
|
||||||
|
$this->check_output_contains_text_input('answer', 'cat');
|
||||||
|
$this->check_output_contains_hidden_input(':sequencecheck', 2);
|
||||||
|
|
||||||
|
// Process an autosave.
|
||||||
|
$this->load_quba();
|
||||||
|
$this->process_autosave(array('answer' => 'frog'));
|
||||||
|
$this->check_current_state(question_state::$complete);
|
||||||
|
$this->check_current_mark(null);
|
||||||
|
$this->check_step_count(3);
|
||||||
|
$this->save_quba();
|
||||||
|
|
||||||
|
// Now check how that is re-displayed.
|
||||||
|
$this->load_quba();
|
||||||
|
$this->render();
|
||||||
|
$this->check_output_contains_text_input('answer', 'frog');
|
||||||
|
$this->check_output_contains_hidden_input(':sequencecheck', 2);
|
||||||
|
|
||||||
|
// Now finishe the attempt, without having done anything since the autosave.
|
||||||
|
$this->finish();
|
||||||
|
$this->save_quba();
|
||||||
|
|
||||||
|
// Now check how that has been graded and is re-displayed.
|
||||||
|
$this->load_quba();
|
||||||
|
$this->check_current_state(question_state::$gradedright);
|
||||||
|
$this->check_current_mark(1);
|
||||||
|
$this->render();
|
||||||
|
$this->check_output_contains_text_input('answer', 'frog', false);
|
||||||
|
$this->check_output_contains_hidden_input(':sequencecheck', 4);
|
||||||
|
|
||||||
|
$this->delete_quba();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue