diff --git a/lib/phpunit/classes/base_testcase.php b/lib/phpunit/classes/base_testcase.php index 231ce1f4198..fcb8786eaa4 100644 --- a/lib/phpunit/classes/base_testcase.php +++ b/lib/phpunit/classes/base_testcase.php @@ -242,7 +242,7 @@ abstract class base_testcase extends PHPUnit_Framework_TestCase { } } // match by exact string else { - if ($node->getAttribute($name) != $value) { + if ($node->getAttribute($name) !== (string) $value) { $invalid = true; } } diff --git a/question/behaviour/manualgraded/tests/walkthrough_test.php b/question/behaviour/manualgraded/tests/walkthrough_test.php index d63030c9248..c47e2053e1b 100644 --- a/question/behaviour/manualgraded/tests/walkthrough_test.php +++ b/question/behaviour/manualgraded/tests/walkthrough_test.php @@ -18,8 +18,7 @@ * This file contains tests that walks a question through the manual graded * behaviour. * - * @package qbehaviour - * @subpackage manualgraded + * @package qbehaviour_manualgraded * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -622,4 +621,40 @@ class qbehaviour_manualgraded_walkthrough_testcase extends qbehaviour_walkthroug new question_pattern_expectation($preg) ); } + + public function test_manual_grading_reshows_exactly_the_mark_input() { + global $PAGE; + + // The current text editor depends on the users profile setting - so it needs a valid user. + $this->setAdminUser(); + // Required to init a text editor. + $PAGE->set_url('/'); + + // Create an essay question graded out of 15 and attempt it. + $essay = test_question_maker::make_an_essay_question(); + $this->start_attempt_at_question($essay, 'deferredfeedback', 15); + $this->process_submission(array('answer' => 'This is my wonderful essay!', 'answerformat' => FORMAT_HTML)); + $this->quba->finish_all_questions(); + + // Verify. + $this->check_current_state(question_state::$needsgrading); + $this->check_current_mark(null); + $this->assertEquals('This is my wonderful essay!', + $this->quba->get_response_summary($this->slot)); + + // Try to process a grade where the score will be stored rounded. + $this->manual_grade('Comment', '5.0', FORMAT_HTML); + + // Verify. + $this->check_current_state(question_state::$mangrpartial); + $this->check_current_mark(5); + $this->displayoptions->manualcomment = question_display_options::EDITABLE; + $this->render(); + $this->check_output_contains_text_input('-mark', '5.0'); + + // Rescale what the question is worth, and verify the display. + $this->get_question_attempt()->set_max_mark(1); + $this->render(); + $this->check_output_contains_text_input('-mark', '0.3333333'); + } } diff --git a/question/behaviour/rendererbase.php b/question/behaviour/rendererbase.php index ea6a1878afe..b47488726e5 100644 --- a/question/behaviour/rendererbase.php +++ b/question/behaviour/rendererbase.php @@ -126,9 +126,6 @@ abstract class qbehaviour_renderer extends plugin_renderer_base { if (!is_null($currentmark)) { $attributes['value'] = $currentmark; } - $a = new stdClass(); - $a->max = $qa->format_max_mark($options->markdp); - $a->mark = html_writer::empty_tag('input', $attributes); $markrange = html_writer::empty_tag('input', array( 'type' => 'hidden', @@ -152,6 +149,9 @@ abstract class qbehaviour_renderer extends plugin_renderer_base { array('class' => 'error')) . html_writer::empty_tag('br'); } + $a = new stdClass(); + $a->max = $qa->format_max_mark($options->markdp); + $a->mark = html_writer::empty_tag('input', $attributes); $mark = html_writer::tag('div', html_writer::tag('div', html_writer::tag('label', get_string('mark', 'question'), array('for' => $markfield)), diff --git a/question/engine/questionattempt.php b/question/engine/questionattempt.php index fa110dde2ae..d295170e3d3 100644 --- a/question/engine/questionattempt.php +++ b/question/engine/questionattempt.php @@ -649,17 +649,29 @@ class question_attempt { /** * This is used by the manual grading code, particularly in association with - * validation. If there is a mark submitted in the request, then use that, - * otherwise use the latest mark for this question. - * @return number the current manual mark for this question, formatted for display. + * validation. It gets the current manual mark for a question, in exactly the string + * form that the teacher entered it, if possible. This may come from the current + * POST request, if there is one, otherwise from the database. + * + * @return string the current manual mark for this question, in the format the teacher typed, + * if possible. */ public function get_current_manual_mark() { + // Is there a current value in the current POST data? If so, use that. $mark = $this->get_submitted_var($this->get_behaviour_field_name('mark'), PARAM_RAW_TRIMMED); - if (is_null($mark)) { - return format_float($this->get_mark(), 7, true, true); - } else { + if ($mark !== null) { return $mark; } + + // Otherwise, use the stored value. + // If the question max mark has not changed, use the stored value that was input. + $storedmaxmark = $this->get_last_behaviour_var('maxmark'); + if ($storedmaxmark !== null && ($storedmaxmark - $this->get_max_mark()) < 0.0000005) { + return $this->get_last_behaviour_var('mark'); + } + + // The max mark for this question has changed so we must re-scale the current mark. + return format_float($this->get_mark(), 7, true, true); } /**