Skip to content
Browse files

MDL-38538 question autosave: fix missing method.

Also change the unit tests to detect this problem.
  • Loading branch information...
1 parent 5957088 commit d122fe3245d0dadb2178e15bd4e6dbb680e3c5f2 @timhunt timhunt committed
View
20 question/engine/questionusage.php
@@ -629,6 +629,26 @@ public function validate_sequence_number($slot, $postdata = null) {
return true;
}
}
+
+ /**
+ * Check, based on the sequence number, whether this auto-save is still required.
+ * @param int $slot the number used to identify this question within this usage.
+ * @param array $submitteddata the submitted data that constitutes the action.
+ * @return bool true if the check variable is present and correct, otherwise false.
+ */
+ public function is_autosave_required($slot, $postdata = null) {
+ $qa = $this->get_question_attempt($slot);
+ $sequencecheck = $qa->get_submitted_var(
+ $qa->get_control_field_name('sequencecheck'), PARAM_INT, $postdata);
+ if (is_null($sequencecheck)) {
+ return false;
+ } else if ($sequencecheck != $qa->get_num_steps()) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
/**
* Update the flagged state for all question_attempts in this usage, if their
* flagged state was changed in the request.
View
27 question/engine/tests/helpers.php
@@ -684,13 +684,12 @@ protected function start_attempt_at_question($question, $preferredbehaviour,
$this->quba->start_question($this->slot, $variant);
}
- protected function process_submission($data) {
- // Backwards compatibility.
- reset($data);
- if (count($data) == 1 && key($data) === '-finish') {
- $this->finish();
- }
-
+ /**
+ * Convert an array of data destined for one question to the equivalent POST data.
+ * @param array $data the data for the quetsion.
+ * @return array the complete post data.
+ */
+ protected function response_data_to_post($data) {
$prefix = $this->quba->get_field_prefix($this->slot);
$fulldata = array(
'slots' => $this->slot,
@@ -699,11 +698,21 @@ protected function process_submission($data) {
foreach ($data as $name => $value) {
$fulldata[$prefix . $name] = $value;
}
- $this->quba->process_all_actions(time(), $fulldata);
+ return $fulldata;
+ }
+
+ protected function process_submission($data) {
+ // Backwards compatibility.
+ reset($data);
+ if (count($data) == 1 && key($data) === '-finish') {
+ $this->finish();
+ }
+
+ $this->quba->process_all_actions(time(), $this->response_data_to_post($data));
}
protected function process_autosave($data) {
- $this->quba->process_autosave($this->slot, $data);
+ $this->quba->process_all_autosaves(null, $this->response_data_to_post($data));
}
protected function finish() {
View
45 question/engine/tests/questionusage_autosave_test.php
@@ -559,4 +559,49 @@ public function test_concurrent_autosaves() {
$DB2->dispose();
}
+
+ public function test_autosave_with_wrong_seq_number_ignored() {
+ $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' => 'first response'));
+
+ $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', 'first response');
+
+ // Process an autosave with a sequence number 1 to small (so from the past).
+ $this->load_quba();
+ $postdata = $this->response_data_to_post(array('answer' => 'obsolete response'));
+ $postdata[$this->quba->get_field_prefix($this->slot) . ':sequencecheck'] = $this->get_question_attempt()->get_num_steps() - 1;
+ $this->quba->process_all_autosaves(null, $postdata);
+ $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->load_quba();
+ $this->render();
+ $this->check_output_contains_text_input('answer', 'first response');
+
+ $this->delete_quba();
+ }
}

0 comments on commit d122fe3

Please sign in to comment.
Something went wrong with that request. Please try again.