See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 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 qtype_multianswer; 18 19 use qtype_multianswer; 20 use question_bank; 21 use question_display_options; 22 use question_hint_with_parts; 23 use question_state; 24 use test_question_maker; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); 30 require_once($CFG->dirroot . '/question/type/multianswer/questiontype.php'); 31 32 33 /** 34 * Unit tests for the multianswer question type. 35 * 36 * @package qtype_multianswer 37 * @copyright 2011 The Open University 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class walkthrough_test extends \qbehaviour_walkthrough_test_base { 41 42 protected function get_contains_subq_status(question_state $state) { 43 return new \question_pattern_expectation('~' . 44 preg_quote($state->default_string(true), '~') . '~'); 45 } 46 47 public function test_deferred_feedback() { 48 49 // Create a multianswer question. 50 $q = \test_question_maker::make_question('multianswer', 'fourmc'); 51 $this->start_attempt_at_question($q, 'deferredfeedback', 4); 52 53 // Check the initial state. 54 $this->check_current_state(question_state::$todo); 55 $this->check_current_mark(null); 56 $this->check_current_output( 57 $this->get_contains_marked_out_of_summary(), 58 $this->get_does_not_contain_feedback_expectation(), 59 $this->get_does_not_contain_validation_error_expectation()); 60 61 // Save in incomplete answer. 62 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '', 63 'sub3_answer' => '', 'sub4_answer' => '')); 64 65 // Verify. 66 $this->check_current_state(question_state::$invalid); 67 $this->check_current_mark(null); 68 $this->check_current_output( 69 $this->get_contains_marked_out_of_summary(), 70 $this->get_does_not_contain_feedback_expectation(), 71 $this->get_contains_validation_error_expectation()); 72 73 // Save a partially correct answer. 74 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 75 'sub3_answer' => '1', 'sub4_answer' => '1')); 76 77 // Verify. 78 $this->check_current_state(question_state::$complete); 79 $this->check_current_mark(null); 80 $this->check_current_output( 81 $this->get_contains_marked_out_of_summary(), 82 $this->get_does_not_contain_feedback_expectation(), 83 $this->get_does_not_contain_validation_error_expectation()); 84 85 // Now submit all and finish. 86 $this->finish(); 87 88 // Verify. 89 $this->check_current_state(question_state::$gradedpartial); 90 $this->check_current_mark(2); 91 $this->check_current_output( 92 $this->get_contains_mark_summary(2), 93 $this->get_contains_partcorrect_expectation(), 94 $this->get_does_not_contain_validation_error_expectation()); 95 } 96 97 public function test_deferred_feedback_numericalzero_not_answered() { 98 // Tests the situation found in MDL-35370. 99 100 // Create a multianswer question with one numerical subquestion, right answer zero. 101 $q = \test_question_maker::make_question('multianswer', 'numericalzero'); 102 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 103 104 // Check the initial state. 105 $this->check_current_state(question_state::$todo); 106 $this->check_current_mark(null); 107 $this->check_current_output( 108 $this->get_contains_marked_out_of_summary(), 109 $this->get_does_not_contain_feedback_expectation(), 110 $this->get_does_not_contain_validation_error_expectation()); 111 112 // Now submit all and finish. 113 $this->finish(); 114 115 // Verify. 116 $this->check_current_state(question_state::$gaveup); 117 $this->check_current_mark(null); 118 $this->check_current_output( 119 $this->get_contains_marked_out_of_summary(), 120 new \question_pattern_expectation('~<input[^>]* class="[^"]*incorrect[^"]*" [^>]*/>~'), 121 $this->get_contains_subq_status(question_state::$gaveup), 122 $this->get_does_not_contain_validation_error_expectation()); 123 } 124 125 public function test_deferred_feedback_numericalzero_0_answer() { 126 // Tests the situation found in MDL-35370. 127 128 // Create a multianswer question with one numerical subquestion, right answer zero. 129 $q = \test_question_maker::make_question('multianswer', 'numericalzero'); 130 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 131 132 // Check the initial state. 133 $this->check_current_state(question_state::$todo); 134 $this->check_current_mark(null); 135 $this->check_current_output( 136 $this->get_contains_marked_out_of_summary(), 137 $this->get_does_not_contain_feedback_expectation(), 138 $this->get_does_not_contain_validation_error_expectation()); 139 140 // Save a the correct answer. 141 $this->process_submission(array('sub1_answer' => '0')); 142 143 // Verify. 144 $this->check_current_state(question_state::$complete); 145 $this->check_current_mark(null); 146 $this->check_current_output( 147 $this->get_contains_marked_out_of_summary(), 148 $this->get_does_not_contain_feedback_expectation(), 149 $this->get_does_not_contain_validation_error_expectation()); 150 151 // Now submit all and finish. 152 $this->finish(); 153 154 // Verify. 155 $this->check_current_state(question_state::$gradedright); 156 $this->check_current_mark(1); 157 $this->check_current_output( 158 $this->get_contains_mark_summary(1), 159 $this->get_contains_correct_expectation(), 160 $this->get_contains_subq_status(question_state::$gradedright), 161 $this->get_does_not_contain_validation_error_expectation()); 162 } 163 164 public function test_deferred_feedback_numericalzero_0_wrong() { 165 // Tests the situation found in MDL-35370. 166 167 // Create a multianswer question with one numerical subquestion, right answer zero. 168 $q = \test_question_maker::make_question('multianswer', 'numericalzero'); 169 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 170 171 // Check the initial state. 172 $this->check_current_state(question_state::$todo); 173 $this->check_current_mark(null); 174 $this->check_current_output( 175 $this->get_contains_marked_out_of_summary(), 176 $this->get_does_not_contain_feedback_expectation(), 177 $this->get_does_not_contain_validation_error_expectation()); 178 179 // Save a the correct answer. 180 $this->process_submission(array('sub1_answer' => '42')); 181 182 // Verify. 183 $this->check_current_state(question_state::$complete); 184 $this->check_current_mark(null); 185 $this->check_current_output( 186 $this->get_contains_marked_out_of_summary(), 187 $this->get_does_not_contain_feedback_expectation(), 188 $this->get_does_not_contain_validation_error_expectation()); 189 190 // Now submit all and finish. 191 $this->finish(); 192 193 // Verify. 194 $this->check_current_state(question_state::$gradedwrong); 195 $this->check_current_mark(0); 196 $this->check_current_output( 197 $this->get_contains_mark_summary(0), 198 $this->get_contains_incorrect_expectation(), 199 $this->get_contains_subq_status(question_state::$gradedwrong), 200 $this->get_does_not_contain_validation_error_expectation()); 201 } 202 203 public function test_interactive_feedback() { 204 205 // Create a multianswer question. 206 $q = \test_question_maker::make_question('multianswer', 'fourmc'); 207 $q->hints = array( 208 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true), 209 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 210 ); 211 $choices = array('0' => 'California', '1' => 'Arizona'); 212 213 $this->start_attempt_at_question($q, 'interactive', 4); 214 215 // Check the initial state. 216 $this->check_current_state(question_state::$todo); 217 $this->check_current_mark(null); 218 $this->assertEquals('interactivecountback', 219 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 220 $this->check_current_output( 221 $this->get_contains_marked_out_of_summary(), 222 $this->get_contains_submit_button_expectation(true), 223 $this->get_does_not_contain_validation_error_expectation(), 224 $this->get_does_not_contain_feedback_expectation(), 225 $this->get_tries_remaining_expectation(3), 226 $this->get_does_not_contain_num_parts_correct(), 227 $this->get_no_hint_visible_expectation()); 228 $this->check_output_contains_selectoptions( 229 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 230 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 231 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 232 $this->get_contains_select_expectation('sub4_answer', $choices, null, true)); 233 234 // Submit a completely wrong response. 235 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '0', 236 'sub3_answer' => '1', 'sub4_answer' => '0', '-submit' => 1)); 237 238 // Verify. 239 $this->check_current_state(question_state::$todo); 240 $this->check_current_mark(null); 241 $this->check_current_output( 242 $this->get_does_not_contain_num_parts_correct(), 243 $this->get_contains_hidden_expectation( 244 $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''), 245 $this->get_contains_hidden_expectation( 246 $this->quba->get_field_prefix($this->slot) . 'sub2_answer', ''), 247 $this->get_contains_hidden_expectation( 248 $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''), 249 $this->get_contains_hidden_expectation( 250 $this->quba->get_field_prefix($this->slot) . 'sub4_answer', ''), 251 $this->get_does_not_contain_submit_button_expectation(), 252 $this->get_contains_try_again_button_expectation(true), 253 $this->get_does_not_contain_correctness_expectation(), 254 $this->get_contains_hint_expectation('This is the first hint.')); 255 $this->check_output_contains_selectoptions( 256 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 257 $this->get_contains_select_expectation('sub2_answer', $choices, 0, false), 258 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 259 $this->get_contains_select_expectation('sub4_answer', $choices, 0, false)); 260 261 // Check that, if we review in this state, the try again button is disabled. 262 $displayoptions = new question_display_options(); 263 $displayoptions->readonly = true; 264 $html = $this->quba->render_question($this->slot, $displayoptions); 265 $this->assert($this->get_contains_try_again_button_expectation(false), $html); 266 267 // Try again. 268 $this->process_submission(array('sub1_answer' => '', 269 'sub2_answer' => '', 'sub3_answer' => '', 270 'sub4_answer' => '', '-tryagain' => 1)); 271 272 // Verify. 273 $this->check_current_state(question_state::$todo); 274 $this->check_current_mark(null); 275 $this->check_current_output( 276 $this->get_contains_submit_button_expectation(true), 277 $this->get_does_not_contain_feedback_expectation(), 278 $this->get_tries_remaining_expectation(2), 279 $this->get_no_hint_visible_expectation()); 280 $this->check_output_contains_selectoptions( 281 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 282 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 283 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 284 $this->get_contains_select_expectation('sub4_answer', $choices, null, true)); 285 286 // Submit a partially wrong response. 287 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 288 'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1)); 289 290 // Verify. 291 $this->check_current_state(question_state::$todo); 292 $this->check_current_mark(null); 293 $this->check_current_output( 294 $this->get_contains_num_parts_correct(2), 295 $this->get_contains_hidden_expectation( 296 $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''), 297 $this->get_contains_hidden_expectation( 298 $this->quba->get_field_prefix($this->slot) . 'sub2_answer', '1'), 299 $this->get_contains_hidden_expectation( 300 $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''), 301 $this->get_contains_hidden_expectation( 302 $this->quba->get_field_prefix($this->slot) . 'sub4_answer', '1'), 303 $this->get_does_not_contain_submit_button_expectation(), 304 $this->get_contains_hint_expectation('This is the second hint.')); 305 $this->check_output_contains_selectoptions( 306 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 307 $this->get_contains_select_expectation('sub2_answer', $choices, 1, false), 308 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 309 $this->get_contains_select_expectation('sub4_answer', $choices, 1, false)); 310 311 // Try again. 312 $this->process_submission(array('sub1_answer' => '', 313 'sub2_answer' => '1', 'sub3_answer' => '', 314 'sub4_answer' => '1', '-tryagain' => 1)); 315 316 // Verify. 317 $this->check_current_state(question_state::$todo); 318 $this->check_current_mark(null); 319 $this->check_current_output( 320 $this->get_contains_submit_button_expectation(true), 321 $this->get_does_not_contain_feedback_expectation(), 322 $this->get_tries_remaining_expectation(1), 323 $this->get_no_hint_visible_expectation()); 324 $this->check_output_contains_selectoptions( 325 $this->get_contains_select_expectation('sub1_answer', $choices, '', true), 326 $this->get_contains_select_expectation('sub2_answer', $choices, '1', true), 327 $this->get_contains_select_expectation('sub3_answer', $choices, '', true), 328 $this->get_contains_select_expectation('sub4_answer', $choices, '1', true)); 329 } 330 331 public function test_interactive_partial_response_does_not_reveal_answer() { 332 333 // Create a multianswer question. 334 $q = \test_question_maker::make_question('multianswer', 'fourmc'); 335 $q->hints = array( 336 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true), 337 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 338 ); 339 $choices = array('0' => 'California', '1' => 'Arizona'); 340 341 $this->start_attempt_at_question($q, 'interactive', 4); 342 343 // Check the initial state. 344 $this->check_current_state(question_state::$todo); 345 $this->check_current_mark(null); 346 $this->assertEquals('interactivecountback', 347 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 348 $this->check_current_output( 349 $this->get_contains_marked_out_of_summary(), 350 $this->get_contains_submit_button_expectation(true), 351 $this->get_does_not_contain_validation_error_expectation(), 352 $this->get_does_not_contain_feedback_expectation(), 353 $this->get_tries_remaining_expectation(3), 354 $this->get_does_not_contain_num_parts_correct(), 355 $this->get_no_hint_visible_expectation()); 356 $this->check_output_contains_selectoptions( 357 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 358 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 359 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 360 $this->get_contains_select_expectation('sub4_answer', $choices, null, true)); 361 362 // Submit an incomplete response response. 363 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', '-submit' => 1)); 364 365 // Verify. 366 $this->check_current_state(question_state::$invalid); 367 $this->check_current_mark(null); 368 $this->check_current_output( 369 $this->get_does_not_contain_num_parts_correct(), 370 $this->get_contains_validation_error_expectation(), 371 $this->get_contains_submit_button_expectation(true), 372 $this->get_does_not_contain_try_again_button_expectation(), 373 $this->get_does_not_contain_correctness_expectation(), 374 $this->get_no_hint_visible_expectation()); 375 $this->check_output_contains_selectoptions( 376 $this->get_contains_select_expectation('sub1_answer', $choices, 1, true), 377 $this->get_contains_select_expectation('sub2_answer', $choices, 1, true), 378 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 379 $this->get_contains_select_expectation('sub4_answer', $choices, null, true)); 380 $this->render(); 381 $a = array('mark' => '0.00', 'max' => '1.00'); 382 $this->assertDoesNotMatchRegularExpression('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~', 383 $this->currentoutput); 384 $a['mark'] = '1.00'; 385 $this->assertDoesNotMatchRegularExpression('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~', 386 $this->currentoutput); 387 } 388 389 public function test_interactivecountback_feedback() { 390 391 // Create a multianswer question. 392 $q = \test_question_maker::make_question('multianswer', 'fourmc'); 393 $q->hints = array( 394 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, true, true), 395 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 396 ); 397 $choices = array('0' => 'California', '1' => 'Arizona'); 398 399 $this->start_attempt_at_question($q, 'interactive', 12); 400 401 // Check the initial state. 402 $this->check_current_state(question_state::$todo); 403 $this->check_current_mark(null); 404 $this->assertEquals('interactivecountback', 405 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 406 $this->check_current_output( 407 $this->get_contains_marked_out_of_summary(), 408 $this->get_contains_submit_button_expectation(true), 409 $this->get_does_not_contain_validation_error_expectation(), 410 $this->get_does_not_contain_feedback_expectation(), 411 $this->get_tries_remaining_expectation(3), 412 $this->get_no_hint_visible_expectation()); 413 $this->check_output_contains_selectoptions( 414 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 415 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 416 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 417 $this->get_contains_select_expectation('sub4_answer', $choices, null, true)); 418 419 // Submit an answer with two right, and two wrong. 420 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 421 'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1)); 422 423 // Verify. 424 $this->check_current_state(question_state::$todo); 425 $this->check_current_mark(null); 426 $this->check_current_output( 427 $this->get_does_not_contain_submit_button_expectation(), 428 $this->get_contains_try_again_button_expectation(true), 429 $this->get_does_not_contain_correctness_expectation(), 430 new \question_pattern_expectation('/Tries remaining: 2/'), 431 $this->get_contains_hint_expectation('This is the first hint.')); 432 $this->check_output_contains_selectoptions( 433 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 434 $this->get_contains_select_expectation('sub2_answer', $choices, 1, false), 435 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 436 $this->get_contains_select_expectation('sub4_answer', $choices, 1, false)); 437 438 // Check that extract responses will return the reset data. 439 $prefix = $this->quba->get_field_prefix($this->slot); 440 $this->assertEquals(array('sub1_answer' => 1), 441 $this->quba->extract_responses($this->slot, array($prefix . 'sub1_answer' => 1))); 442 443 // Do try again. 444 $this->process_submission(array('sub1_answer' => '', 445 'sub2_answer' => '1', 'sub3_answer' => '', 446 'sub4_answer' => '1', '-tryagain' => 1)); 447 448 // Verify. 449 $this->check_current_state(question_state::$todo); 450 $this->check_current_mark(null); 451 $this->check_current_output( 452 $this->get_contains_submit_button_expectation(true), 453 $this->get_does_not_contain_feedback_expectation(), 454 $this->get_tries_remaining_expectation(2), 455 $this->get_no_hint_visible_expectation()); 456 $this->check_output_contains_selectoptions( 457 $this->get_contains_select_expectation('sub1_answer', $choices, '', true), 458 $this->get_contains_select_expectation('sub2_answer', $choices, '1', true), 459 $this->get_contains_select_expectation('sub3_answer', $choices, '', true), 460 $this->get_contains_select_expectation('sub4_answer', $choices, '1', true)); 461 462 // Submit the right answer. 463 $this->process_submission(array('sub1_answer' => '0', 'sub2_answer' => '1', 464 'sub3_answer' => '0', 'sub4_answer' => '1', '-submit' => 1)); 465 466 // Verify. 467 $this->check_current_state(question_state::$gradedright); 468 $this->check_current_mark(10); 469 $this->check_current_output( 470 $this->get_does_not_contain_submit_button_expectation(), 471 $this->get_does_not_contain_try_again_button_expectation(), 472 $this->get_contains_correct_expectation(), 473 new \question_no_pattern_expectation('/class="control\b[^"]*\bpartiallycorrect"/')); 474 $this->check_output_contains_selectoptions( 475 $this->get_contains_select_expectation('sub1_answer', $choices, '0', false), 476 $this->get_contains_select_expectation('sub2_answer', $choices, '1', false), 477 $this->get_contains_select_expectation('sub3_answer', $choices, '0', false), 478 $this->get_contains_select_expectation('sub4_answer', $choices, '1', false)); 479 } 480 481 public function test_deferred_feedback_multiple() { 482 483 // Create a multianswer question. 484 $q = \test_question_maker::make_question('multianswer', 'multiple'); 485 $this->start_attempt_at_question($q, 'deferredfeedback', 2); 486 487 // Check the initial state. 488 $this->check_current_state(question_state::$todo); 489 $this->check_current_mark(null); 490 $this->check_current_output( 491 $this->get_contains_marked_out_of_summary(), 492 $this->get_does_not_contain_feedback_expectation(), 493 $this->get_does_not_contain_validation_error_expectation()); 494 495 // Save in incomplete answer. 496 $this->process_submission(array('sub1_choice0' => '1', 'sub1_choice1' => '1', 497 'sub1_choice2' => '', 'sub1_choice3' => '', 498 'sub1_choice4' => '', 'sub1_choice5' => '1', 499 )); 500 501 // Verify. 502 $this->check_current_state(question_state::$invalid); 503 $this->check_current_mark(null); 504 $this->check_current_output( 505 $this->get_contains_marked_out_of_summary(), 506 $this->get_does_not_contain_feedback_expectation(), 507 $this->get_contains_validation_error_expectation()); 508 509 // Save a partially correct answer. 510 $this->process_submission(array('sub1_choice0' => '1', 'sub1_choice1' => '', 511 'sub1_choice2' => '', 'sub1_choice3' => '', 512 'sub1_choice4' => '1', 'sub1_choice5' => '1', 513 'sub2_choice0' => '', 'sub2_choice1' => '', 514 'sub2_choice2' => '', 'sub2_choice3' => '', 515 'sub2_choice4' => '1', 516 )); 517 518 // Verify. 519 $this->check_current_state(question_state::$complete); 520 $this->check_current_mark(null); 521 $this->check_current_output( 522 $this->get_contains_marked_out_of_summary(), 523 $this->get_does_not_contain_feedback_expectation(), 524 $this->get_does_not_contain_validation_error_expectation()); 525 526 // Now submit all and finish. 527 $this->finish(); 528 529 // Verify. 530 $this->check_current_state(question_state::$gradedpartial); 531 $this->check_current_mark(1.5); 532 $this->check_current_output( 533 $this->get_contains_mark_summary(1.5), 534 $this->get_contains_partcorrect_expectation(), 535 $this->get_does_not_contain_validation_error_expectation()); 536 } 537 538 /** 539 * Test corrupted question display. 540 * 541 * @covers \qtype_multianswer_renderer::subquestion 542 */ 543 public function test_corrupted_question() { 544 global $DB; 545 546 $syscontext = \context_system::instance(); 547 $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); 548 $category = $generator->create_question_category(['contextid' => $syscontext->id]); 549 550 $fromform = test_question_maker::get_question_form_data('multianswer', 'twosubq'); 551 $fromform->category = $category->id . ',' . $syscontext->id; 552 553 $question = new \stdClass(); 554 $question->category = $category->id; 555 $question->qtype = 'multianswer'; 556 $question->createdby = 0; 557 558 $question = (new qtype_multianswer)->save_question($question, $fromform); 559 $questiondata = question_bank::load_question_data($question->id); 560 $questiontodeletekey = array_keys($questiondata->options->questions)[0]; 561 $questiontodelete = $questiondata->options->questions[$questiontodeletekey]; 562 $DB->delete_records('question', ['id' => $questiontodelete->id]); 563 564 question_bank::notify_question_edited($question->id); 565 $question = question_bank::load_question($question->id); 566 567 $this->start_attempt_at_question($question, 'deferredfeedback', 2); 568 $this->check_current_output( 569 $this->get_contains_marked_out_of_summary(), 570 $this->get_does_not_contain_feedback_expectation(), 571 $this->get_does_not_contain_validation_error_expectation(), 572 $this->get_contains_corruption_notification(), 573 $this->get_contains_corrupted_subquestion_message(), 574 ); 575 } 576 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body