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