MDL-64420 qtype: gapselect unit tests unsafe
[moodle.git] / question / type / randomsamatch / tests / walkthrough_test.php
CommitLineData
93a54393
JMV
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/**
18 * This file contains tests that walks a question through the interactive
19 * behaviour.
20 *
21 * @package qtype_randomsamatch
22 * @copyright 2013 Jean-Michel Vedrine
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
31
32
33/**
34 * Unit tests for the randomsamatch question type.
35 *
36 * @copyright 2013 Jean-Michel Vedrine
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 */
39class qtype_randomsamatch_walkthrough_test extends qbehaviour_walkthrough_test_base {
40
41 public function test_deferred_feedback_unanswered() {
42
43 // Create a randomsamatch question.
44 $m = test_question_maker::make_question('randomsamatch');
45 $this->start_attempt_at_question($m, 'deferredfeedback', 4);
46
47 $choiceorder = $m->get_choice_order();
48 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 49 $choices = [];
93a54393
JMV
50 foreach ($choiceorder as $key => $choice) {
51 $choices[$key] = $m->choices[$choice];
52 }
53
54 // Check the initial state.
55 $this->check_current_state(question_state::$todo);
56 $this->check_current_mark(null);
57 $this->check_current_output(
0d3be6d6
JB
58 $this->get_contains_question_text_expectation($m),
59 $this->get_does_not_contain_feedback_expectation());
60 $this->check_output_contains_selectoptions(
93a54393
JMV
61 $this->get_contains_select_expectation('sub0', $choices, null, true),
62 $this->get_contains_select_expectation('sub1', $choices, null, true),
63 $this->get_contains_select_expectation('sub2', $choices, null, true),
0d3be6d6 64 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
65 $this->check_step_count(1);
66
67 // Save a blank response.
68 $this->process_submission(array('sub0' => '0', 'sub1' => '0',
69 'sub2' => '0', 'sub3' => '0'));
70
71 // Verify.
72 $this->check_current_state(question_state::$todo);
73 $this->check_current_mark(null);
74 $this->check_current_output(
0d3be6d6
JB
75 $this->get_contains_question_text_expectation($m),
76 $this->get_does_not_contain_feedback_expectation());
77 $this->check_output_contains_selectoptions(
93a54393
JMV
78 $this->get_contains_select_expectation('sub0', $choices, null, true),
79 $this->get_contains_select_expectation('sub1', $choices, null, true),
80 $this->get_contains_select_expectation('sub2', $choices, null, true),
0d3be6d6 81 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
82 $this->check_step_count(1);
83
84 // Finish the attempt.
85 $this->quba->finish_all_questions();
86
87 // Verify.
88 $this->check_current_state(question_state::$gaveup);
89 $this->check_current_mark(null);
0d3be6d6 90 $this->check_output_contains_selectoptions(
93a54393
JMV
91 $this->get_contains_select_expectation('sub0', $choices, null, false),
92 $this->get_contains_select_expectation('sub1', $choices, null, false),
93 $this->get_contains_select_expectation('sub2', $choices, null, false),
94 $this->get_contains_select_expectation('sub3', $choices, null, false));
95 }
96
97 public function test_deferred_feedback_partial_answer() {
98
99 // Create a randomsamatching question.
100 $m = test_question_maker::make_question('randomsamatch');
101 $m->shufflestems = false;
102 $this->start_attempt_at_question($m, 'deferredfeedback', 4);
103
104 $choiceorder = $m->get_choice_order();
105 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 106 $choices = [];
93a54393
JMV
107 foreach ($choiceorder as $key => $choice) {
108 $choices[$key] = $m->choices[$choice];
109 }
110
111 // Check the initial state.
112 $this->check_current_state(question_state::$todo);
113 $this->check_current_mark(null);
114 $this->check_current_output(
0d3be6d6
JB
115 $this->get_contains_question_text_expectation($m),
116 $this->get_does_not_contain_feedback_expectation());
117 $this->check_output_contains_selectoptions(
93a54393
JMV
118 $this->get_contains_select_expectation('sub0', $choices, null, true),
119 $this->get_contains_select_expectation('sub1', $choices, null, true),
120 $this->get_contains_select_expectation('sub2', $choices, null, true),
0d3be6d6 121 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
122
123 // Save a partial response.
124 $this->process_submission(array('sub0' => $orderforchoice[13],
125 'sub1' => $orderforchoice[16], 'sub2' => '0', 'sub3' => '0'));
126
127 // Verify.
128 $this->check_current_state(question_state::$invalid);
129 $this->check_current_mark(null);
130 $this->check_current_output(
0d3be6d6
JB
131 $this->get_contains_question_text_expectation($m),
132 $this->get_does_not_contain_feedback_expectation());
133 $this->check_output_contains_selectoptions(
93a54393
JMV
134 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[13], true),
135 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[16], true),
136 $this->get_contains_select_expectation('sub2', $choices, null, true),
0d3be6d6 137 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
138
139 // Finish the attempt.
140 $this->quba->finish_all_questions();
141
142 // Verify.
143 $this->check_current_state(question_state::$gradedpartial);
144 $this->check_current_mark(2);
145 $this->check_current_output(
0d3be6d6
JB
146 $this->get_contains_partcorrect_expectation());
147 $this->check_output_contains_selectoptions(
93a54393
JMV
148 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[13], false),
149 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[16], false),
150 $this->get_contains_select_expectation('sub2', $choices, null, false),
0d3be6d6 151 $this->get_contains_select_expectation('sub3', $choices, null, false));
93a54393
JMV
152 }
153
154 public function test_interactive_correct_no_submit() {
155
156 // Create a randomsamatching question.
157 $m = test_question_maker::make_question('randomsamatch');
158 $m->hints = array(
159 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
160 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
161 );
162 $m->shufflestems = false;
163 $this->start_attempt_at_question($m, 'interactive', 4);
164
165 $choiceorder = $m->get_choice_order();
166 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 167 $choices = [];
93a54393
JMV
168 foreach ($choiceorder as $key => $choice) {
169 $choices[$key] = $m->choices[$choice];
170 }
171
172 // Check the initial state.
173 $this->check_current_state(question_state::$todo);
174 $this->check_current_mark(null);
175 $this->check_current_output(
93a54393
JMV
176 $this->get_contains_submit_button_expectation(true),
177 $this->get_does_not_contain_feedback_expectation(),
178 $this->get_tries_remaining_expectation(3),
179 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
180 $this->check_output_contains_selectoptions(
181 $this->get_contains_select_expectation('sub0', $choices, null, true),
182 $this->get_contains_select_expectation('sub1', $choices, null, true),
183 $this->get_contains_select_expectation('sub2', $choices, null, true),
184 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
185
186 // Save the right answer.
187 $this->process_submission(array('sub0' => $orderforchoice[13],
188 'sub1' => $orderforchoice[16], 'sub2' => $orderforchoice[16],
189 'sub3' => $orderforchoice[13]));
190
191 // Finish the attempt without clicking check.
192 $this->quba->finish_all_questions();
193
194 // Verify.
195 $this->check_current_state(question_state::$gradedright);
196 $this->check_current_mark(4);
197 $this->check_current_output(
81e47a35 198 $this->get_does_not_contain_submit_button_expectation(),
93a54393
JMV
199 $this->get_contains_correct_expectation(),
200 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
201 $this->check_output_contains_selectoptions(
202 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[13], false),
203 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[16], false),
204 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[16], false),
205 $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[13], false));
93a54393
JMV
206 }
207
208 public function test_interactive_partial_no_submit() {
209
210 // Create a randomsamatching question.
211 $m = test_question_maker::make_question('randomsamatch');
212 $m->hints = array(
213 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
214 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
215 );
216 $m->shufflestems = false;
217 $this->start_attempt_at_question($m, 'interactive', 4);
218
219 $choiceorder = $m->get_choice_order();
220 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 221 $choices = [];
93a54393
JMV
222 foreach ($choiceorder as $key => $choice) {
223 $choices[$key] = $m->choices[$choice];
224 }
225
226 // Check the initial state.
227 $this->check_current_state(question_state::$todo);
228 $this->check_current_mark(null);
229 $this->check_current_output(
93a54393
JMV
230 $this->get_contains_submit_button_expectation(true),
231 $this->get_does_not_contain_feedback_expectation(),
232 $this->get_tries_remaining_expectation(3),
233 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
234 $this->check_output_contains_selectoptions(
235 $this->get_contains_select_expectation('sub0', $choices, null, true),
236 $this->get_contains_select_expectation('sub1', $choices, null, true),
237 $this->get_contains_select_expectation('sub2', $choices, null, true),
238 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
239
240 // Save the right answer.
241 $this->process_submission(array('sub0' => $orderforchoice[13],
242 'sub1' => $orderforchoice[16], 'sub2' => $orderforchoice[13],
243 'sub3' => '0'));
244
245 // Finish the attempt without clicking check.
246 $this->quba->finish_all_questions();
247
248 // Verify.
249 $this->check_current_state(question_state::$gradedpartial);
250 $this->check_current_mark(2);
251 $this->check_current_output(
81e47a35 252 $this->get_does_not_contain_submit_button_expectation(),
93a54393
JMV
253 $this->get_contains_partcorrect_expectation(),
254 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
255 $this->check_output_contains_selectoptions(
256 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[13], false),
257 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[16], false),
258 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[13], false),
259 $this->get_contains_select_expectation('sub3', $choices, null, false));
93a54393
JMV
260 }
261
262 public function test_interactive_with_invalid() {
263
264 // Create a randomsamatching question.
265 $m = test_question_maker::make_question('randomsamatch');
266 $m->hints = array(
267 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
268 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
269 );
270 $m->shufflestems = false;
271 $this->start_attempt_at_question($m, 'interactive', 4);
272
273 $choiceorder = $m->get_choice_order();
274 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 275 $choices = [];
93a54393
JMV
276 foreach ($choiceorder as $key => $choice) {
277 $choices[$key] = $m->choices[$choice];
278 }
279
280 // Check the initial state.
281 $this->check_current_state(question_state::$todo);
282 $this->check_current_mark(null);
283 $this->check_current_output(
93a54393
JMV
284 $this->get_contains_submit_button_expectation(true),
285 $this->get_does_not_contain_feedback_expectation(),
286 $this->get_tries_remaining_expectation(3),
287 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
288 $this->check_output_contains_selectoptions(
289 $this->get_contains_select_expectation('sub0', $choices, null, true),
290 $this->get_contains_select_expectation('sub1', $choices, null, true),
291 $this->get_contains_select_expectation('sub2', $choices, null, true),
292 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
293
294 // Try to submit an invalid answer.
295 $this->process_submission(array('sub0' => '0',
296 'sub1' => '0', 'sub2' => '0',
297 'sub3' => '0', '-submit' => '1'));
298
299 // Verify.
300 $this->check_current_state(question_state::$invalid);
301 $this->check_current_mark(null);
302 $this->check_current_output(
93a54393
JMV
303 $this->get_contains_submit_button_expectation(true),
304 $this->get_does_not_contain_feedback_expectation(),
305 $this->get_invalid_answer_expectation(),
306 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
307 $this->check_output_contains_selectoptions(
308 $this->get_contains_select_expectation('sub0', $choices, null, true),
309 $this->get_contains_select_expectation('sub1', $choices, null, true),
310 $this->get_contains_select_expectation('sub2', $choices, null, true),
311 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
312
313 // Now submit the right answer.
314 $this->process_submission(array('sub0' => $orderforchoice[13],
315 'sub1' => $orderforchoice[16], 'sub2' => $orderforchoice[16],
316 'sub3' => $orderforchoice[13], '-submit' => '1'));
317
318 // Verify.
319 $this->check_current_state(question_state::$gradedright);
320 $this->check_current_mark(4);
321 $this->check_current_output(
81e47a35 322 $this->get_does_not_contain_submit_button_expectation(),
93a54393
JMV
323 $this->get_contains_correct_expectation(),
324 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
325 $this->check_output_contains_selectoptions(
326 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[13], false),
327 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[16], false),
328 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[16], false),
329 $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[13], false));
93a54393
JMV
330 }
331
332 public function test_randomsamatch_clear_wrong() {
333
334 // Create a randomsamatching question.
335 $m = test_question_maker::make_question('randomsamatch');
336 $m->hints = array(
337 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true),
338 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
339 );
340 $m->shufflestems = false;
341 $this->start_attempt_at_question($m, 'interactive', 4);
342
343 $choiceorder = $m->get_choice_order();
344 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
0d3be6d6 345 $choices = [];
93a54393
JMV
346 foreach ($choiceorder as $key => $choice) {
347 $choices[$key] = $m->choices[$choice];
348 }
349
350 // Check the initial state.
351 $this->check_current_state(question_state::$todo);
352 $this->check_current_mark(null);
353 $this->check_current_output(
93a54393
JMV
354 $this->get_contains_submit_button_expectation(true),
355 $this->get_does_not_contain_feedback_expectation(),
356 $this->get_tries_remaining_expectation(3),
357 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
358 $this->check_output_contains_selectoptions(
359 $this->get_contains_select_expectation('sub0', $choices, null, true),
360 $this->get_contains_select_expectation('sub1', $choices, null, true),
361 $this->get_contains_select_expectation('sub2', $choices, null, true),
362 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
363
364 // Submit a completely wrong response.
365 $this->process_submission(array('sub0' => $orderforchoice[16],
366 'sub1' => $orderforchoice[13], 'sub2' => $orderforchoice[13],
367 'sub3' => $orderforchoice[16], '-submit' => 1));
368
369 // Verify.
370 $this->check_current_state(question_state::$todo);
371 $this->check_current_mark(null);
372 $this->check_current_output(
93a54393
JMV
373 $this->get_contains_hidden_expectation(
374 $this->quba->get_field_prefix($this->slot) . 'sub0', '0'),
375 $this->get_contains_hidden_expectation(
376 $this->quba->get_field_prefix($this->slot) . 'sub1', '0'),
377 $this->get_contains_hidden_expectation(
378 $this->quba->get_field_prefix($this->slot) . 'sub2', '0'),
379 $this->get_contains_hidden_expectation(
380 $this->quba->get_field_prefix($this->slot) . 'sub3', '0'),
81e47a35 381 $this->get_does_not_contain_submit_button_expectation(),
93a54393 382 $this->get_contains_hint_expectation('This is the first hint.'));
0d3be6d6
JB
383 $this->check_output_contains_selectoptions(
384 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[16], false),
385 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[13], false),
386 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[13], false),
387 $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[16], false));
93a54393
JMV
388
389 // Try again.
390 $this->process_submission(array('sub0' => 0,
391 'sub1' => 0, 'sub2' => 0,
392 'sub3' => 0, '-tryagain' => 1));
393
394 // Verify.
395 $this->check_current_state(question_state::$todo);
396 $this->check_current_mark(null);
397 $this->check_current_output(
93a54393
JMV
398 $this->get_contains_submit_button_expectation(true),
399 $this->get_does_not_contain_feedback_expectation(),
400 $this->get_tries_remaining_expectation(2),
401 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
402 $this->check_output_contains_selectoptions(
403 $this->get_contains_select_expectation('sub0', $choices, null, true),
404 $this->get_contains_select_expectation('sub1', $choices, null, true),
405 $this->get_contains_select_expectation('sub2', $choices, null, true),
406 $this->get_contains_select_expectation('sub3', $choices, null, true));
93a54393
JMV
407
408 // Submit a partially wrong response.
409 $this->process_submission(array('sub0' => $orderforchoice[16],
410 'sub1' => $orderforchoice[13], 'sub2' => $orderforchoice[16],
411 'sub3' => $orderforchoice[13], '-submit' => 1));
412
413 // Verify.
414 $this->check_current_state(question_state::$todo);
415 $this->check_current_mark(null);
416 $this->check_current_output(
93a54393
JMV
417 $this->get_contains_hidden_expectation(
418 $this->quba->get_field_prefix($this->slot) . 'sub0', '0'),
419 $this->get_contains_hidden_expectation(
420 $this->quba->get_field_prefix($this->slot) . 'sub1', '0'),
421 $this->get_contains_hidden_expectation(
422 $this->quba->get_field_prefix($this->slot) . 'sub2', $orderforchoice[16]),
423 $this->get_contains_hidden_expectation(
424 $this->quba->get_field_prefix($this->slot) . 'sub3', $orderforchoice[13]),
81e47a35 425 $this->get_does_not_contain_submit_button_expectation(),
93a54393 426 $this->get_contains_hint_expectation('This is the second hint.'));
0d3be6d6
JB
427 $this->check_output_contains_selectoptions(
428 $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[16], false),
429 $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[13], false),
430 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[16], false),
431 $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[13], false));
93a54393
JMV
432
433 // Try again.
434 $this->process_submission(array('sub0' => 0,
435 'sub1' => 0, 'sub2' => $orderforchoice[16],
436 'sub3' => $orderforchoice[13], '-tryagain' => 1));
437
438 // Verify.
439 $this->check_current_state(question_state::$todo);
440 $this->check_current_mark(null);
441 $this->check_current_output(
93a54393
JMV
442 $this->get_contains_submit_button_expectation(true),
443 $this->get_does_not_contain_feedback_expectation(),
444 $this->get_tries_remaining_expectation(1),
445 $this->get_no_hint_visible_expectation());
0d3be6d6
JB
446 $this->check_output_contains_selectoptions(
447 $this->get_contains_select_expectation('sub0', $choices, null, true),
448 $this->get_contains_select_expectation('sub1', $choices, null, true),
449 $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[16], true),
450 $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[13], true));
93a54393
JMV
451 }
452}