Merge branch 'MDL-38538_clean' of git://github.com/timhunt/moodle
authorDan Poltawski <dan@moodle.com>
Wed, 3 Apr 2013 01:55:21 +0000 (09:55 +0800)
committerDan Poltawski <dan@moodle.com>
Wed, 3 Apr 2013 01:55:21 +0000 (09:55 +0800)
question/engine/questionusage.php
question/engine/tests/helpers.php
question/engine/tests/questionusage_autosave_test.php

index 77541e2..a1f9494 100644 (file)
@@ -629,6 +629,26 @@ class question_usage_by_activity {
             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.
index be6dd29..8ff4e44 100644 (file)
@@ -684,13 +684,12 @@ abstract class qbehaviour_walkthrough_test_base extends question_testcase {
         $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 @@ abstract class qbehaviour_walkthrough_test_base extends question_testcase {
         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() {
index 9090d42..304c941 100644 (file)
@@ -559,4 +559,49 @@ class question_usage_autosave_test extends qbehaviour_walkthrough_test_base {
 
         $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();
+    }
 }