Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace qbehaviour_immediatefeedback;
  18  
  19  use question_state;
  20  
  21  defined('MOODLE_INTERNAL') || die();
  22  
  23  global $CFG;
  24  require_once (__DIR__ . '/../../../engine/lib.php');
  25  require_once (__DIR__ . '/../../../engine/tests/helpers.php');
  26  
  27  
  28  /**
  29   * Unit tests for the immediate feedback behaviour.
  30   *
  31   * @package    qbehaviour_immediatefeedback
  32   * @copyright  2009 The Open University
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class walkthrough_test extends \qbehaviour_walkthrough_test_base {
  36      public function test_immediatefeedback_feedback_multichoice_right() {
  37  
  38          // Create a true-false question with correct answer true.
  39          $mc = \test_question_maker::make_a_multichoice_single_question();
  40          $this->start_attempt_at_question($mc, 'immediatefeedback');
  41  
  42          $rightindex = $this->get_mc_right_answer_index($mc);
  43          $wrongindex = ($rightindex + 1) % 3;
  44  
  45          // Check the initial state.
  46          $this->check_current_state(question_state::$todo);
  47          $this->check_current_mark(null);
  48          $this->check_current_output(
  49                  $this->get_contains_question_text_expectation($mc),
  50                  $this->get_contains_mc_radio_expectation(0, true, false),
  51                  $this->get_contains_mc_radio_expectation(1, true, false),
  52                  $this->get_contains_mc_radio_expectation(2, true, false),
  53                  $this->get_contains_submit_button_expectation(true),
  54                  $this->get_does_not_contain_feedback_expectation());
  55  
  56          // Save the wrong answer.
  57          $this->process_submission(array('answer' => $wrongindex));
  58  
  59          // Verify.
  60          $this->check_current_state(question_state::$todo);
  61          $this->check_current_mark(null);
  62          $this->check_current_output(
  63                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
  64                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  65                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  66                  $this->get_contains_submit_button_expectation(true),
  67                  $this->get_does_not_contain_correctness_expectation(),
  68                  $this->get_does_not_contain_feedback_expectation());
  69  
  70          // Submit the right answer.
  71          $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
  72  
  73          // Verify.
  74          $this->check_current_state(question_state::$gradedright);
  75          $this->check_current_mark(1);
  76          $this->check_current_output(
  77                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
  78                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  79                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  80                  $this->get_contains_correct_expectation());
  81          $this->assertEquals('A',
  82                  $this->quba->get_response_summary($this->slot));
  83  
  84          $numsteps = $this->get_step_count();
  85  
  86          // Now try to save again - as if the user clicked next in the quiz.
  87          $this->process_submission(array('answer' => $rightindex));
  88  
  89          // Verify.
  90          $this->assertEquals($numsteps, $this->get_step_count());
  91          $this->check_current_state(question_state::$gradedright);
  92          $this->check_current_mark(1);
  93          $this->check_current_output(
  94                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
  95                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  96                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  97                  $this->get_contains_correct_expectation());
  98  
  99          // Finish the attempt - should not need to add a new state.
 100          $this->quba->finish_all_questions();
 101  
 102          // Verify.
 103          $this->assertEquals($numsteps, $this->get_step_count());
 104          $this->check_current_state(question_state::$gradedright);
 105          $this->check_current_mark(1);
 106          $this->check_current_output(
 107                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 108                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 109                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 110                  $this->get_contains_correct_expectation());
 111  
 112          // Process a manual comment.
 113          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 114  
 115          // Verify.
 116          $this->check_current_state(question_state::$mangrpartial);
 117          $this->check_current_mark(0.5);
 118          $this->check_current_output(
 119                  $this->get_contains_partcorrect_expectation(),
 120                  new \question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 121  
 122          // Now change the correct answer to the question, and regrade.
 123          $mc->answers[13]->fraction = -0.33333333;
 124          $mc->answers[15]->fraction = 1;
 125          $this->quba->regrade_all_questions();
 126  
 127          // Verify.
 128          $this->check_current_state(question_state::$mangrpartial);
 129          $this->check_current_mark(0.5);
 130          $this->check_current_output(
 131                  $this->get_contains_partcorrect_expectation());
 132  
 133          $autogradedstep = $this->get_step($this->get_step_count() - 2);
 134          $this->assertEqualsWithDelta($autogradedstep->get_fraction(), -0.3333333, 0.0000001);
 135      }
 136  
 137      public function test_immediatefeedback_feedback_multichoice_try_to_submit_blank() {
 138  
 139          // Create a true-false question with correct answer true.
 140          $mc = \test_question_maker::make_a_multichoice_single_question();
 141          $this->start_attempt_at_question($mc, 'immediatefeedback');
 142  
 143          // Check the initial state.
 144          $this->check_current_state(question_state::$todo);
 145          $this->check_current_mark(null);
 146          $this->check_current_output(
 147                  $this->get_contains_question_text_expectation($mc),
 148                  $this->get_contains_mc_radio_expectation(0, true, false),
 149                  $this->get_contains_mc_radio_expectation(1, true, false),
 150                  $this->get_contains_mc_radio_expectation(2, true, false),
 151                  $this->get_contains_submit_button_expectation(true),
 152                  $this->get_does_not_contain_feedback_expectation());
 153  
 154          // Submit nothing.
 155          $this->process_submission(array('-submit' => 1));
 156  
 157          // Verify.
 158          $this->check_current_state(question_state::$invalid);
 159          $this->check_current_mark(null);
 160          $this->check_current_output(
 161                  $this->get_contains_mc_radio_expectation(0, true, false),
 162                  $this->get_contains_mc_radio_expectation(1, true, false),
 163                  $this->get_contains_mc_radio_expectation(2, true, false),
 164                  $this->get_contains_submit_button_expectation(true),
 165                  $this->get_does_not_contain_correctness_expectation(),
 166                  $this->get_does_not_contain_feedback_expectation(),
 167                  $this->get_contains_validation_error_expectation());
 168          $this->assertNull($this->quba->get_response_summary($this->slot));
 169  
 170          // Finish the attempt.
 171          $this->quba->finish_all_questions();
 172  
 173          // Verify.
 174          $this->check_current_state(question_state::$gaveup);
 175          $this->check_current_mark(null);
 176          $this->check_current_output(
 177                  $this->get_contains_mc_radio_expectation(0, false, false),
 178                  $this->get_contains_mc_radio_expectation(1, false, false),
 179                  $this->get_contains_mc_radio_expectation(2, false, false));
 180  
 181          // Process a manual comment.
 182          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 183  
 184          // Verify.
 185          $this->check_current_state(question_state::$mangrpartial);
 186          $this->check_current_mark(0.5);
 187          $this->check_current_output(
 188                  $this->get_contains_partcorrect_expectation(),
 189                  new \question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 190      }
 191  
 192      public function test_immediatefeedback_feedback_multichoice_wrong_on_finish() {
 193  
 194          // Create a true-false question with correct answer true.
 195          $mc = \test_question_maker::make_a_multichoice_single_question();
 196          $this->start_attempt_at_question($mc, 'immediatefeedback');
 197  
 198          // Check the initial state.
 199          $this->check_current_state(question_state::$todo);
 200          $this->check_current_mark(null);
 201          $this->check_current_output(
 202                  $this->get_contains_question_text_expectation($mc),
 203                  $this->get_contains_mc_radio_expectation(0, true, false),
 204                  $this->get_contains_mc_radio_expectation(1, true, false),
 205                  $this->get_contains_mc_radio_expectation(2, true, false),
 206                  $this->get_contains_submit_button_expectation(true),
 207                  $this->get_does_not_contain_feedback_expectation());
 208  
 209          $rightindex = $this->get_mc_right_answer_index($mc);
 210          $wrongindex = ($rightindex + 1) % 3;
 211  
 212          // Save the wrong answer.
 213          $this->process_submission(array('answer' => $wrongindex));
 214  
 215          // Verify.
 216          $this->check_current_state(question_state::$todo);
 217          $this->check_current_mark(null);
 218          $this->check_current_output(
 219                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
 220                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 221                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 222                  $this->get_contains_submit_button_expectation(true),
 223                  $this->get_does_not_contain_correctness_expectation(),
 224                  $this->get_does_not_contain_feedback_expectation());
 225  
 226          // Finish the attempt.
 227          $this->quba->finish_all_questions();
 228  
 229          // Verify.
 230          $this->check_current_state(question_state::$gradedwrong);
 231          $this->check_current_mark(-0.3333333);
 232          $this->check_current_output(
 233                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
 234                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 235                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 236                  $this->get_contains_incorrect_expectation());
 237          $this->assertMatchesRegularExpression('/B|C/',
 238                  $this->quba->get_response_summary($this->slot));
 239      }
 240  }