MDL-47494 ddimageortext: Fix unit tests for 3.0 compatibility.
[moodle.git] / question / type / ddimageortext / tests / walkthrough_test.php
CommitLineData
c7b2d1fb
JP
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 * Unit tests for the drag-and-drop onto image question type.
19 *
66d2356b
TH
20 * @package qtype_ddimageortext
21 * @copyright 2010 The Open University
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
c7b2d1fb
JP
23 */
24
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
30require_once($CFG->dirroot . '/question/type/ddimageortext/tests/helper.php');
31
32
33/**
34 * Unit tests for the drag-and-drop onto image question type.
35 *
66d2356b
TH
36 * @copyright 2010 The Open University
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
c7b2d1fb
JP
38 */
39class qtype_ddimageortext_walkthrough_test extends qbehaviour_walkthrough_test_base {
40
51c3521a
TH
41 /**
42 * Get an expectation that the output contains an item ready to drag.
43 * @param int $dragitemno the item number.
44 * @param int $choice which choice this is.
45 * @param int $group which drag group it belongs to.
46 * @return question_contains_tag_with_attributes the required expectation.
47 */
c7b2d1fb
JP
48 protected function get_contains_drag_image_home_expectation($dragitemno, $choice, $group) {
49 $class = 'group' . $group;
50 $class .= ' draghome dragitemhomes' . $dragitemno. ' choice'.$choice.' yui3-cssfonts';
51
52 $expectedattrs = array();
53 $expectedattrs['class'] = $class;
54
55 return new question_contains_tag_with_attributes('div', $expectedattrs);
56 }
57
58 public function test_interactive_behaviour() {
59
60 // Create a drag-and-drop question.
61 $dd = test_question_maker::make_question('ddimageortext');
62 $dd->hints = array(
63 new question_hint_with_parts(13, 'This is the first hint.', FORMAT_HTML, false, false),
64 new question_hint_with_parts(14, 'This is the second hint.', FORMAT_HTML, true, true),
65 );
66 $dd->shufflechoices = false;
67 $this->start_attempt_at_question($dd, 'interactive', 12);
68
69 // Check the initial state.
70 $this->check_current_state(question_state::$todo);
71 $this->check_current_mark(null);
72
73 $this->check_current_output(
74 $this->get_contains_drag_image_home_expectation(1, 1, 1),
75 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
76 $this->get_contains_drag_image_home_expectation(3, 1, 2),
77 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
78 $this->get_contains_hidden_expectation(
79 $this->quba->get_field_prefix($this->slot) . 'p1'),
80 $this->get_contains_hidden_expectation(
81 $this->quba->get_field_prefix($this->slot) . 'p2'),
82 $this->get_contains_hidden_expectation(
83 $this->quba->get_field_prefix($this->slot) . 'p3'),
84 $this->get_contains_hidden_expectation(
85 $this->quba->get_field_prefix($this->slot) . 'p4'),
86 $this->get_contains_submit_button_expectation(true),
87 $this->get_does_not_contain_feedback_expectation(),
88 $this->get_tries_remaining_expectation(3),
89 $this->get_no_hint_visible_expectation());
90
91 // Save the wrong answer.
92 $this->process_submission(array('p1' => '2', 'p2' => '1', 'p3' => '2', 'p4' => '1'));
93 // Verify.
94 $this->check_current_state(question_state::$todo);
95 $this->check_current_mark(null);
96
97 $this->check_current_output(
98 $this->get_contains_drag_image_home_expectation(1, 1, 1),
99 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
100 $this->get_contains_drag_image_home_expectation(3, 1, 2),
101 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
102 $this->get_contains_hidden_expectation(
103 $this->quba->get_field_prefix($this->slot) . 'p1', 2),
104 $this->get_contains_hidden_expectation(
105 $this->quba->get_field_prefix($this->slot) . 'p2', 1),
106 $this->get_contains_hidden_expectation(
107 $this->quba->get_field_prefix($this->slot) . 'p3', 2),
108 $this->get_contains_hidden_expectation(
109 $this->quba->get_field_prefix($this->slot) . 'p4', 1),
110 $this->get_contains_submit_button_expectation(true),
111 $this->get_does_not_contain_feedback_expectation(),
112 $this->get_tries_remaining_expectation(3),
113 $this->get_no_hint_visible_expectation());
114 // Submit the wrong answer.
115 $this->process_submission(
116 array('p1' => '2', 'p2' => '1', 'p3' => '2', 'p4' => '1', '-submit' => 1));
117
118 // Verify.
119 $this->check_current_state(question_state::$todo);
120 $this->check_current_mark(null);
121 $this->check_current_output(
122 $this->get_contains_drag_image_home_expectation(1, 1, 1),
123 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
124 $this->get_contains_drag_image_home_expectation(3, 1, 2),
125 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
126 $this->get_contains_hidden_expectation(
127 $this->quba->get_field_prefix($this->slot) . 'p1', 2),
128 $this->get_contains_hidden_expectation(
129 $this->quba->get_field_prefix($this->slot) . 'p2', 1),
130 $this->get_contains_hidden_expectation(
131 $this->quba->get_field_prefix($this->slot) . 'p3', 2),
132 $this->get_contains_hidden_expectation(
133 $this->quba->get_field_prefix($this->slot) . 'p4', 1),
134 $this->get_contains_try_again_button_expectation(true),
c7b2d1fb
JP
135 $this->get_contains_hint_expectation('This is the first hint'));
136
137 // Do try again.
138 $this->process_submission(array('-tryagain' => 1));
139
140 // Verify.
141 $this->check_current_state(question_state::$todo);
142 $this->check_current_mark(null);
143
144 $this->check_current_output(
145 $this->get_contains_drag_image_home_expectation(1, 1, 1),
146 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
147 $this->get_contains_drag_image_home_expectation(3, 1, 2),
148 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
149 $this->get_contains_hidden_expectation(
150 $this->quba->get_field_prefix($this->slot) . 'p1', '2'),
151 $this->get_contains_hidden_expectation(
152 $this->quba->get_field_prefix($this->slot) . 'p2', '1'),
153 $this->get_contains_hidden_expectation(
154 $this->quba->get_field_prefix($this->slot) . 'p3', '2'),
155 $this->get_contains_hidden_expectation(
156 $this->quba->get_field_prefix($this->slot) . 'p4', '1'),
157 $this->get_contains_submit_button_expectation(true),
158 $this->get_does_not_contain_correctness_expectation(),
159 $this->get_does_not_contain_feedback_expectation(),
160 $this->get_tries_remaining_expectation(2),
161 $this->get_no_hint_visible_expectation());
162
163 // Submit the right answer.
164 $this->process_submission(
165 array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2', '-submit' => 1));
166
167 // Verify.
168 $this->check_current_state(question_state::$gradedright);
169 $this->check_current_mark(8);
170 $this->check_current_output(
171 $this->get_contains_drag_image_home_expectation(1, 1, 1),
172 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
173 $this->get_contains_drag_image_home_expectation(3, 1, 2),
174 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
175 $this->get_contains_hidden_expectation(
176 $this->quba->get_field_prefix($this->slot) . 'p1', '1'),
177 $this->get_contains_hidden_expectation(
178 $this->quba->get_field_prefix($this->slot) . 'p2', '2'),
179 $this->get_contains_hidden_expectation(
180 $this->quba->get_field_prefix($this->slot) . 'p3', '1'),
181 $this->get_contains_hidden_expectation(
182 $this->quba->get_field_prefix($this->slot) . 'p4', '2'),
183 $this->get_contains_submit_button_expectation(false),
184 $this->get_contains_correct_expectation(),
185 $this->get_no_hint_visible_expectation());
186
187 // Check regrading does not mess anything up.
188 $this->quba->regrade_all_questions();
189
190 // Verify.
191 $this->check_current_state(question_state::$gradedright);
192 $this->check_current_mark(8);
193 }
194
195 public function test_deferred_feedback() {
196
197 // Create a drag-and-drop question.
198 $dd = test_question_maker::make_question('ddimageortext');
199 $dd->shufflechoices = false;
200 $this->start_attempt_at_question($dd, 'deferredfeedback', 12);
201
202 // Check the initial state.
203 $this->check_current_state(question_state::$todo);
204 $this->check_current_mark(null);
205
206 $this->check_current_output(
207 $this->get_contains_drag_image_home_expectation(1, 1, 1),
208 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
209 $this->get_contains_drag_image_home_expectation(3, 1, 2),
210 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
211 $this->get_contains_hidden_expectation(
212 $this->quba->get_field_prefix($this->slot) . 'p1'),
213 $this->get_contains_hidden_expectation(
214 $this->quba->get_field_prefix($this->slot) . 'p2'),
215 $this->get_contains_hidden_expectation(
216 $this->quba->get_field_prefix($this->slot) . 'p3'),
217 $this->get_contains_hidden_expectation(
218 $this->quba->get_field_prefix($this->slot) . 'p4'),
219 $this->get_does_not_contain_feedback_expectation());
220
221 // Save a partial answer.
222 $this->process_submission(array('p1' => '2', 'p2' => '1'));
223 // Verify.
224 $this->check_current_state(question_state::$invalid);
225 $this->check_current_mark(null);
226
227 $this->check_current_output(
228 $this->get_contains_drag_image_home_expectation(1, 1, 1),
229 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
230 $this->get_contains_drag_image_home_expectation(3, 1, 2),
231 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
232 $this->get_contains_hidden_expectation(
233 $this->quba->get_field_prefix($this->slot) . 'p1', 2),
234 $this->get_contains_hidden_expectation(
235 $this->quba->get_field_prefix($this->slot) . 'p2', 1),
236 $this->get_contains_hidden_expectation(
237 $this->quba->get_field_prefix($this->slot) . 'p3', ''),
238 $this->get_contains_hidden_expectation(
239 $this->quba->get_field_prefix($this->slot) . 'p4', ''),
240 $this->get_does_not_contain_correctness_expectation(),
241 $this->get_does_not_contain_feedback_expectation());
242 // Save the right answer.
243 $this->process_submission(
244 array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2'));
245
246 // Verify.
247 $this->check_current_state(question_state::$complete);
248 $this->check_current_mark(null);
249 $this->check_current_output(
250 $this->get_contains_drag_image_home_expectation(1, 1, 1),
251 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
252 $this->get_contains_drag_image_home_expectation(3, 1, 2),
253 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
254 $this->get_contains_hidden_expectation(
255 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
256 $this->get_contains_hidden_expectation(
257 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
258 $this->get_contains_hidden_expectation(
259 $this->quba->get_field_prefix($this->slot) . 'p3', 1),
260 $this->get_contains_hidden_expectation(
261 $this->quba->get_field_prefix($this->slot) . 'p4', 2),
262 $this->get_does_not_contain_correctness_expectation(),
263 $this->get_does_not_contain_feedback_expectation());
264
265 // Finish the attempt.
266 $this->quba->finish_all_questions();
267
268 // Verify.
269 $this->check_current_state(question_state::$gradedright);
270 $this->check_current_mark(12);
271
272 $this->check_current_output(
273 $this->get_contains_drag_image_home_expectation(1, 1, 1),
274 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
275 $this->get_contains_drag_image_home_expectation(3, 1, 2),
276 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
277 $this->get_contains_hidden_expectation(
278 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
279 $this->get_contains_hidden_expectation(
280 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
281 $this->get_contains_hidden_expectation(
282 $this->quba->get_field_prefix($this->slot) . 'p3', 1),
283 $this->get_contains_hidden_expectation(
284 $this->quba->get_field_prefix($this->slot) . 'p4', 2),
285 $this->get_contains_correct_expectation());
286
287 // Change the right answer a bit.
288 $dd->rightchoices[2] = 1;
289
290 // Check regrading does not mess anything up.
291 $this->quba->regrade_all_questions();
292
293 // Verify.
294 $this->check_current_state(question_state::$gradedpartial);
295 $this->check_current_mark(9);
296 }
297
298 public function test_deferred_feedback_unanswered() {
299
300 // Create a drag-and-drop question.
301 $dd = test_question_maker::make_question('ddimageortext');
302 $dd->shufflechoices = false;
303 $this->start_attempt_at_question($dd, 'deferredfeedback', 12);
304
305 // Check the initial state.
306 $this->check_current_state(question_state::$todo);
307 $this->check_current_mark(null);
308 $this->check_current_output(
309 $this->get_contains_drag_image_home_expectation(1, 1, 1),
310 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
311 $this->get_contains_drag_image_home_expectation(3, 1, 2),
312 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
313 $this->get_contains_hidden_expectation(
314 $this->quba->get_field_prefix($this->slot) . 'p1'),
315 $this->get_contains_hidden_expectation(
316 $this->quba->get_field_prefix($this->slot) . 'p2'),
317 $this->get_contains_hidden_expectation(
318 $this->quba->get_field_prefix($this->slot) . 'p3'),
319 $this->get_contains_hidden_expectation(
320 $this->quba->get_field_prefix($this->slot) . 'p4'),
321 $this->get_does_not_contain_correctness_expectation(),
322 $this->get_does_not_contain_feedback_expectation());
323 $this->check_step_count(1);
324
325 // Save a blank response.
326 $this->process_submission(array('p1' => '', 'p2' => '', 'p3' => '', 'p4' => ''));
327
328 // Verify.
329 $this->check_current_state(question_state::$todo);
330 $this->check_current_mark(null);
331 $this->check_current_output(
332 $this->get_contains_drag_image_home_expectation(1, 1, 1),
333 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
334 $this->get_contains_drag_image_home_expectation(3, 1, 2),
335 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
336 $this->get_contains_hidden_expectation(
337 $this->quba->get_field_prefix($this->slot) . 'p1', ''),
338 $this->get_contains_hidden_expectation(
339 $this->quba->get_field_prefix($this->slot) . 'p2', ''),
340 $this->get_contains_hidden_expectation(
341 $this->quba->get_field_prefix($this->slot) . 'p3', ''),
342 $this->get_contains_hidden_expectation(
343 $this->quba->get_field_prefix($this->slot) . 'p4', ''),
344 $this->get_does_not_contain_correctness_expectation(),
345 $this->get_does_not_contain_feedback_expectation());
346 $this->check_step_count(1);
347
348 // Finish the attempt.
349 $this->quba->finish_all_questions();
350
351 // Verify.
352 $this->check_current_state(question_state::$gaveup);
353 $this->check_current_mark(null);
354 $this->check_current_output(
355 $this->get_contains_drag_image_home_expectation(1, 1, 1),
356 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
357 $this->get_contains_drag_image_home_expectation(3, 1, 2),
358 $this->get_contains_drag_image_home_expectation(4, 2, 2));
c7b2d1fb
JP
359 }
360
361 public function test_deferred_feedback_partial_answer() {
362
363 // Create a drag-and-drop question.
364 $dd = test_question_maker::make_question('ddimageortext');
365 $dd->shufflechoices = false;
366 $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
367
368 // Check the initial state.
369 $this->check_current_state(question_state::$todo);
370 $this->check_current_mark(null);
371 $this->check_current_output(
372 $this->get_contains_drag_image_home_expectation(1, 1, 1),
373 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
374 $this->get_contains_drag_image_home_expectation(3, 1, 2),
375 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
376 $this->get_contains_hidden_expectation(
377 $this->quba->get_field_prefix($this->slot) . 'p1'),
378 $this->get_contains_hidden_expectation(
379 $this->quba->get_field_prefix($this->slot) . 'p2'),
380 $this->get_contains_hidden_expectation(
381 $this->quba->get_field_prefix($this->slot) . 'p3'),
382 $this->get_contains_hidden_expectation(
383 $this->quba->get_field_prefix($this->slot) . 'p4'),
384 $this->get_does_not_contain_correctness_expectation(),
385 $this->get_does_not_contain_feedback_expectation());
386
387 // Save a partial response.
388 $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '', 'p4' => ''));
389
390 // Verify.
391 $this->check_current_state(question_state::$invalid);
392 $this->check_current_mark(null);
393 $this->check_current_output(
394 $this->get_contains_drag_image_home_expectation(1, 1, 1),
395 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
396 $this->get_contains_drag_image_home_expectation(3, 1, 2),
397 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
398 $this->get_contains_hidden_expectation(
399 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
400 $this->get_contains_hidden_expectation(
401 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
402 $this->get_contains_hidden_expectation(
09e43f0a 403 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
c7b2d1fb 404 $this->get_contains_hidden_expectation(
09e43f0a 405 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
c7b2d1fb
JP
406 $this->get_does_not_contain_correctness_expectation(),
407 $this->get_does_not_contain_feedback_expectation());
408
409 // Finish the attempt.
410 $this->quba->finish_all_questions();
411
412 // Verify.
413 $this->check_current_state(question_state::$gradedpartial);
414 $this->check_current_mark(1.5);
415 $this->check_current_output(
416 $this->get_contains_drag_image_home_expectation(1, 1, 1),
417 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
418 $this->get_contains_drag_image_home_expectation(3, 1, 2),
419 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
420 $this->get_contains_partcorrect_expectation());
421 }
422
423 public function test_interactive_grading() {
424
425 // Create a drag-and-drop question.
426 $dd = test_question_maker::make_question('ddimageortext');
427 $dd->hints = array(
428 new question_hint_with_parts(1, 'This is the first hint.',
429 FORMAT_MOODLE, true, true),
430 new question_hint_with_parts(2, 'This is the second hint.',
431 FORMAT_MOODLE, true, true),
432 );
433 $dd->shufflechoices = false;
434 $this->start_attempt_at_question($dd, 'interactive', 12);
435
436 // Check the initial state.
437 $this->check_current_state(question_state::$todo);
438 $this->check_current_mark(null);
439 $this->assertEquals('interactivecountback',
440 $this->quba->get_question_attempt($this->slot)->get_behaviour_name());
441 $this->check_current_output(
442 $this->get_contains_drag_image_home_expectation(1, 1, 1),
443 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
444 $this->get_contains_drag_image_home_expectation(3, 1, 2),
445 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
446 $this->get_contains_hidden_expectation(
447 $this->quba->get_field_prefix($this->slot) . 'p1'),
448 $this->get_contains_hidden_expectation(
449 $this->quba->get_field_prefix($this->slot) . 'p2'),
450 $this->get_contains_hidden_expectation(
451 $this->quba->get_field_prefix($this->slot) . 'p3'),
452 $this->get_contains_hidden_expectation(
453 $this->quba->get_field_prefix($this->slot) . 'p4'),
454 $this->get_contains_submit_button_expectation(true),
455 $this->get_does_not_contain_feedback_expectation(),
456 $this->get_tries_remaining_expectation(3),
457 $this->get_does_not_contain_num_parts_correct(),
458 $this->get_no_hint_visible_expectation());
459
460 // Submit an response with the first two parts right.
461 $this->process_submission(
462 array('p1' => '1', 'p2' => '2', 'p3' => '2', 'p4' => '1', '-submit' => 1));
463
464 // Verify.
465 $this->check_current_state(question_state::$todo);
466 $this->check_current_mark(null);
467 $this->check_current_output(
468 $this->get_contains_drag_image_home_expectation(1, 1, 1),
469 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
470 $this->get_contains_drag_image_home_expectation(3, 1, 2),
471 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
472 $this->get_contains_submit_button_expectation(false),
473 $this->get_contains_try_again_button_expectation(true),
474 $this->get_does_not_contain_correctness_expectation(),
c7b2d1fb
JP
475 $this->get_contains_hint_expectation('This is the first hint'),
476 $this->get_contains_num_parts_correct(2),
477 $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(),
478 $this->get_contains_hidden_expectation(
479 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
480 $this->get_contains_hidden_expectation(
481 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
482 $this->get_contains_hidden_expectation(
483 $this->quba->get_field_prefix($this->slot) . 'p3', 2),
484 $this->get_contains_hidden_expectation(
485 $this->quba->get_field_prefix($this->slot) . 'p4', 1));
486
487 // Check that extract responses will return the reset data.
488 $prefix = $this->quba->get_field_prefix($this->slot);
489 $this->assertEquals(array('p1' => '1', 'p2' => '2'),
490 $this->quba->extract_responses($this->slot,
491 array($prefix . 'p1' => '1', $prefix . 'p2' => '2', '-tryagain' => 1)));
492
493 // Do try again.
494 // keys p3 and p4 are extra hidden fields to clear data.
495 $this->process_submission(
496 array('p1' => '1', 'p2' => '2', 'p3' => '', 'p4' => '', '-tryagain' => 1));
497
498 // Verify.
499 $this->check_current_state(question_state::$todo);
500 $this->check_current_mark(null);
501 $this->check_current_output(
502 $this->get_contains_drag_image_home_expectation(1, 1, 1),
503 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
504 $this->get_contains_drag_image_home_expectation(3, 1, 2),
505 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
506 $this->get_contains_hidden_expectation(
507 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
508 $this->get_contains_hidden_expectation(
509 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
510 $this->get_contains_hidden_expectation(
09e43f0a 511 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
c7b2d1fb 512 $this->get_contains_hidden_expectation(
09e43f0a 513 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
c7b2d1fb
JP
514 $this->get_contains_submit_button_expectation(true),
515 $this->get_does_not_contain_try_again_button_expectation(),
516 $this->get_does_not_contain_correctness_expectation(),
517 $this->get_does_not_contain_feedback_expectation(),
518 $this->get_tries_remaining_expectation(2),
519 $this->get_no_hint_visible_expectation());
520
521 // Submit an response with the first and last parts right.
522 $this->process_submission(
523 array('p1' => '1', 'p2' => '1', 'p3' => '2', 'p4' => '2', '-submit' => 1));
524
525 // Verify.
526 $this->check_current_state(question_state::$todo);
527 $this->check_current_mark(null);
528 $this->check_current_output(
529 $this->get_contains_drag_image_home_expectation(1, 1, 1),
530 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
531 $this->get_contains_drag_image_home_expectation(3, 1, 2),
532 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
533 $this->get_contains_submit_button_expectation(false),
534 $this->get_contains_try_again_button_expectation(true),
535 $this->get_does_not_contain_correctness_expectation(),
c7b2d1fb
JP
536 $this->get_contains_hint_expectation('This is the second hint'),
537 $this->get_contains_num_parts_correct(2),
538 $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(),
539 $this->get_contains_hidden_expectation(
540 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
541 $this->get_contains_hidden_expectation(
542 $this->quba->get_field_prefix($this->slot) . 'p2', 1),
543 $this->get_contains_hidden_expectation(
544 $this->quba->get_field_prefix($this->slot) . 'p3', 2),
545 $this->get_contains_hidden_expectation(
546 $this->quba->get_field_prefix($this->slot) . 'p4', 2));
547
548 // Do try again.
549 $this->process_submission(
550 array('p1' => '1', 'p2' => '', 'p3' => '', 'p4' => '2', '-tryagain' => 1));
551
552 // Verify.
553 $this->check_current_state(question_state::$todo);
554 $this->check_current_mark(null);
555 $this->check_current_output(
556 $this->get_contains_drag_image_home_expectation(1, 1, 1),
557 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
558 $this->get_contains_drag_image_home_expectation(3, 1, 2),
559 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
560 $this->get_contains_hidden_expectation(
561 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
562 $this->get_contains_hidden_expectation(
09e43f0a 563 $this->quba->get_field_prefix($this->slot) . 'p2', 0),
c7b2d1fb 564 $this->get_contains_hidden_expectation(
09e43f0a 565 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
c7b2d1fb
JP
566 $this->get_contains_hidden_expectation(
567 $this->quba->get_field_prefix($this->slot) . 'p4', 2),
568 $this->get_contains_submit_button_expectation(true),
569 $this->get_does_not_contain_try_again_button_expectation(),
570 $this->get_does_not_contain_correctness_expectation(),
571 $this->get_does_not_contain_feedback_expectation(),
572 $this->get_tries_remaining_expectation(1),
573 $this->get_no_hint_visible_expectation());
574
575 // Submit the right answer.
576 $this->process_submission(
577 array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2', '-submit' => 1));
578
579 // Verify.
580 $this->check_current_state(question_state::$gradedright);
581 $this->check_current_mark(7);
582 $this->check_current_output(
583 $this->get_contains_drag_image_home_expectation(1, 1, 1),
584 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
585 $this->get_contains_drag_image_home_expectation(3, 1, 2),
586 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
587 $this->get_contains_hidden_expectation(
588 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
589 $this->get_contains_hidden_expectation(
590 $this->quba->get_field_prefix($this->slot) . 'p2', 2),
591 $this->get_contains_hidden_expectation(
592 $this->quba->get_field_prefix($this->slot) . 'p3', 1),
593 $this->get_contains_hidden_expectation(
594 $this->quba->get_field_prefix($this->slot) . 'p4', 2),
595 $this->get_contains_submit_button_expectation(false),
596 $this->get_does_not_contain_try_again_button_expectation(),
597 $this->get_contains_correct_expectation(),
598 $this->get_no_hint_visible_expectation(),
599 $this->get_does_not_contain_num_parts_correct(),
600 $this->get_contains_standard_correct_combined_feedback_expectation());
601 }
602
603 public function test_interactive_correct_no_submit() {
604
605 // Create a drag-and-drop question.
606 $dd = test_question_maker::make_question('ddimageortext');
607 $dd->hints = array(
608 new question_hint_with_parts(23, 'This is the first hint.',
609 FORMAT_MOODLE, false, false),
610 new question_hint_with_parts(24, 'This is the second hint.',
611 FORMAT_MOODLE, true, true),
612 );
613 $dd->shufflechoices = false;
614 $this->start_attempt_at_question($dd, 'interactive', 3);
615
616 // Check the initial state.
617 $this->check_current_state(question_state::$todo);
618 $this->check_current_mark(null);
619 $this->check_current_output(
620 $this->get_contains_drag_image_home_expectation(1, 1, 1),
621 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
622 $this->get_contains_drag_image_home_expectation(3, 1, 2),
623 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
624 $this->get_contains_hidden_expectation(
625 $this->quba->get_field_prefix($this->slot) . 'p1'),
626 $this->get_contains_hidden_expectation(
627 $this->quba->get_field_prefix($this->slot) . 'p2'),
628 $this->get_contains_hidden_expectation(
629 $this->quba->get_field_prefix($this->slot) . 'p3'),
630 $this->get_contains_hidden_expectation(
631 $this->quba->get_field_prefix($this->slot) . 'p4'),
632 $this->get_contains_submit_button_expectation(true),
633 $this->get_does_not_contain_feedback_expectation(),
634 $this->get_tries_remaining_expectation(3),
635 $this->get_no_hint_visible_expectation());
636
637 // Save the right answer.
638 $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2'));
639
640 // Finish the attempt without clicking check.
641 $this->quba->finish_all_questions();
642
643 // Verify.
644 $this->check_current_state(question_state::$gradedright);
645 $this->check_current_mark(3);
646 $this->check_current_output(
647 $this->get_contains_drag_image_home_expectation(1, 1, 1),
648 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
649 $this->get_contains_drag_image_home_expectation(3, 1, 2),
650 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
651 $this->get_contains_submit_button_expectation(false),
652 $this->get_contains_correct_expectation(),
653 $this->get_no_hint_visible_expectation());
654
655 // Check regrading does not mess anything up.
656 $this->quba->regrade_all_questions();
657
658 // Verify.
659 $this->check_current_state(question_state::$gradedright);
660 $this->check_current_mark(3);
661 }
662
663 public function test_interactive_partial_no_submit() {
664
665 // Create a drag-and-drop question.
666 $dd = test_question_maker::make_question('ddimageortext');
667 $dd->hints = array(
668 new question_hint_with_parts(23, 'This is the first hint.',
669 FORMAT_MOODLE, false, false),
670 new question_hint_with_parts(24, 'This is the second hint.',
671 FORMAT_MOODLE, true, true),
672 );
673 $dd->shufflechoices = false;
674 $this->start_attempt_at_question($dd, 'interactive', 4);
675
676 // Check the initial state.
677 $this->check_current_state(question_state::$todo);
678 $this->check_current_mark(null);
679
680 $this->check_current_output(
681 $this->get_contains_drag_image_home_expectation(1, 1, 1),
682 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
683 $this->get_contains_drag_image_home_expectation(3, 1, 2),
684 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
685 $this->get_contains_hidden_expectation(
686 $this->quba->get_field_prefix($this->slot) . 'p1'),
687 $this->get_contains_hidden_expectation(
688 $this->quba->get_field_prefix($this->slot) . 'p2'),
689 $this->get_contains_hidden_expectation(
690 $this->quba->get_field_prefix($this->slot) . 'p3'),
691 $this->get_contains_hidden_expectation(
692 $this->quba->get_field_prefix($this->slot) . 'p4'),
693 $this->get_contains_submit_button_expectation(true),
694 $this->get_does_not_contain_feedback_expectation(),
695 $this->get_tries_remaining_expectation(3),
696 $this->get_no_hint_visible_expectation());
697
698 // Save the a partially right answer.
699 $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '2', 'p4' => '1'));
700
701 // Finish the attempt without clicking check.
702 $this->quba->finish_all_questions();
703
704 // Verify.
705 $this->check_current_state(question_state::$gradedpartial);
706 $this->check_current_mark(1);
707
708 $this->check_current_output(
709 $this->get_contains_drag_image_home_expectation(1, 1, 1),
710 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
711 $this->get_contains_drag_image_home_expectation(3, 1, 2),
712 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
713 $this->get_contains_submit_button_expectation(false),
714 $this->get_contains_partcorrect_expectation(),
715 $this->get_no_hint_visible_expectation());
716
717 // Check regrading does not mess anything up.
718 $this->quba->regrade_all_questions();
719
720 // Verify.
721 $this->check_current_state(question_state::$gradedpartial);
722 $this->check_current_mark(1);
723 }
724
725 public function test_interactive_no_right_clears() {
726
727 // Create a drag-and-drop question.
728 $dd = test_question_maker::make_question('ddimageortext');
729 $dd->hints = array(
730 new question_hint_with_parts(23, 'This is the first hint.', FORMAT_MOODLE, false, true),
731 new question_hint_with_parts(24, 'This is the second hint.', FORMAT_MOODLE, true, true),
732 );
733 $dd->shufflechoices = false;
734 $this->start_attempt_at_question($dd, 'interactive', 3);
735
736 // Check the initial state.
737 $this->check_current_state(question_state::$todo);
738 $this->check_current_mark(null);
739
740 $this->check_current_output(
741 $this->get_contains_marked_out_of_summary(),
742 $this->get_contains_drag_image_home_expectation(1, 1, 1),
743 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
744 $this->get_contains_drag_image_home_expectation(3, 1, 2),
745 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
746 $this->get_contains_hidden_expectation(
747 $this->quba->get_field_prefix($this->slot) . 'p1'),
748 $this->get_contains_hidden_expectation(
749 $this->quba->get_field_prefix($this->slot) . 'p2'),
750 $this->get_contains_hidden_expectation(
751 $this->quba->get_field_prefix($this->slot) . 'p3'),
752 $this->get_contains_hidden_expectation(
753 $this->quba->get_field_prefix($this->slot) . 'p4'),
754 $this->get_contains_submit_button_expectation(true),
755 $this->get_does_not_contain_feedback_expectation(),
756 $this->get_tries_remaining_expectation(3),
757 $this->get_no_hint_visible_expectation());
758
759 // Save the a completely wrong answer.
760 $this->process_submission(
761 array('p1' => '2', 'p2' => '1', 'p3' => '2', 'p4' => '1', '-submit' => 1));
762
763 // Verify.
764 $this->check_current_state(question_state::$todo);
765 $this->check_current_mark(null);
766 $this->check_current_output(
767 $this->get_contains_marked_out_of_summary(),
768 $this->get_contains_drag_image_home_expectation(1, 1, 1),
769 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
770 $this->get_contains_drag_image_home_expectation(3, 1, 2),
771 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb
JP
772 $this->get_contains_submit_button_expectation(false),
773 $this->get_contains_hint_expectation('This is the first hint'));
774
775 // Do try again.
776 $this->process_submission(
777 array('p1' => '', 'p2' => '', 'p3' => '', 'p4' => '', '-tryagain' => 1));
778
779 // Check that all the wrong answers have been cleared.
780 $this->check_current_state(question_state::$todo);
781 $this->check_current_mark(null);
782 $this->check_current_output(
783 $this->get_contains_marked_out_of_summary(),
784 $this->get_contains_drag_image_home_expectation(1, 1, 1),
785 $this->get_contains_drag_image_home_expectation(2, 2, 1),
2bf2e46c
TH
786 $this->get_contains_drag_image_home_expectation(3, 1, 2),
787 $this->get_contains_drag_image_home_expectation(4, 2, 2),
c7b2d1fb 788 $this->get_contains_hidden_expectation(
09e43f0a 789 $this->quba->get_field_prefix($this->slot) . 'p1', 0),
c7b2d1fb 790 $this->get_contains_hidden_expectation(
09e43f0a 791 $this->quba->get_field_prefix($this->slot) . 'p2', 0),
c7b2d1fb 792 $this->get_contains_hidden_expectation(
09e43f0a 793 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
c7b2d1fb 794 $this->get_contains_hidden_expectation(
09e43f0a 795 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
c7b2d1fb
JP
796 $this->get_contains_submit_button_expectation(true),
797 $this->get_does_not_contain_feedback_expectation(),
798 $this->get_tries_remaining_expectation(2),
799 $this->get_no_hint_visible_expectation());
800 }
801
802 public function test_display_of_right_answer_when_shuffled() {
803
804 // Create a drag-and-drop question.
805 $dd = test_question_maker::make_question('ddimageortext');
806 $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
807
808 // Check the initial state.
809 $this->check_current_state(question_state::$todo);
810 $this->check_current_mark(null);
811
812 $this->check_current_output(
813 $this->get_contains_hidden_expectation(
814 $this->quba->get_field_prefix($this->slot) . 'p1'),
815 $this->get_contains_hidden_expectation(
816 $this->quba->get_field_prefix($this->slot) . 'p2'),
817 $this->get_contains_hidden_expectation(
818 $this->quba->get_field_prefix($this->slot) . 'p3'),
819 $this->get_contains_hidden_expectation(
820 $this->quba->get_field_prefix($this->slot) . 'p4'),
821 $this->get_does_not_contain_feedback_expectation());
822
823 // Save a partial answer.
824 $this->process_submission($dd->get_correct_response());
825
826 // Verify.
827 $this->check_current_state(question_state::$complete);
828 $this->check_current_mark(null);
829 $this->check_current_output(
830 $this->get_contains_hidden_expectation(
831 $this->quba->get_field_prefix($this->slot) . 'p1',
832 $dd->get_right_choice_for(1)),
833 $this->get_contains_hidden_expectation(
834 $this->quba->get_field_prefix($this->slot) . 'p2',
835 $dd->get_right_choice_for(2)),
836 $this->get_contains_hidden_expectation(
837 $this->quba->get_field_prefix($this->slot) . 'p3',
838 $dd->get_right_choice_for(3)),
839 $this->get_contains_hidden_expectation(
840 $this->quba->get_field_prefix($this->slot) . 'p4',
841 $dd->get_right_choice_for(4)),
842 $this->get_does_not_contain_correctness_expectation(),
843 $this->get_does_not_contain_feedback_expectation());
844
845 // Finish the attempt.
846 $this->quba->finish_all_questions();
847
848 // Verify.
849 $this->displayoptions->rightanswer = question_display_options::VISIBLE;
850 $this->assertEquals('Drop zone 1 -> {1. quick} '.
851 'Drop zone 2 -> {2. fox} '.
2bf2e46c
TH
852 'Drop zone 3 -> {3. lazy} '.
853 'Drop zone 4 -> {4. dog}',
c7b2d1fb
JP
854 $dd->get_right_answer_summary());
855 $this->check_current_state(question_state::$gradedright);
856 $this->check_current_mark(3);
857 }
858}