MDL-70153 qtype_essay: Add behat test for attachments max size
[moodle.git] / question / type / ddimageortext / tests / walkthrough_test.php
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/>.
17 /**
18  * Unit tests for the drag-and-drop onto image question type.
19  *
20  * @package   qtype_ddimageortext
21  * @copyright 2010 The Open University
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
30 require_once($CFG->dirroot . '/question/type/ddimageortext/tests/helper.php');
33 /**
34  * Unit tests for the drag-and-drop onto image question type.
35  *
36  * @copyright 2010 The Open University
37  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class qtype_ddimageortext_walkthrough_test extends qbehaviour_walkthrough_test_base {
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      */
48     protected function get_contains_drag_image_home_expectation($dragitemno, $choice, $group) {
49         $class = 'group' . $group . ' draghome choice' . $choice;
51         $expectedattrs = array();
52         $expectedattrs['class'] = $class;
54         return new question_contains_tag_with_attributes('div', $expectedattrs);
55     }
57     public function test_interactive_behaviour() {
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);
68         // Check the initial state.
69         $this->check_current_state(question_state::$todo);
70         $this->check_current_mark(null);
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),
75             $this->get_contains_drag_image_home_expectation(3, 1, 2),
76             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
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);
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),
99             $this->get_contains_drag_image_home_expectation(3, 1, 2),
100             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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));
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),
123             $this->get_contains_drag_image_home_expectation(3, 1, 2),
124             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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),
134             $this->get_contains_hint_expectation('This is the first hint'));
136         // Do try again.
137         $this->process_submission(array('-tryagain' => 1));
139         // Verify.
140         $this->check_current_state(question_state::$todo);
141         $this->check_current_mark(null);
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),
146             $this->get_contains_drag_image_home_expectation(3, 1, 2),
147             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
162         // Submit the right answer.
163         $this->process_submission(
164             array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2', '-submit' => 1));
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),
172             $this->get_contains_drag_image_home_expectation(3, 1, 2),
173             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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'),
182             $this->get_does_not_contain_submit_button_expectation(),
183             $this->get_contains_correct_expectation(),
184             $this->get_no_hint_visible_expectation());
186         // Check regrading does not mess anything up.
187         $this->quba->regrade_all_questions();
189         // Verify.
190         $this->check_current_state(question_state::$gradedright);
191         $this->check_current_mark(8);
192     }
194     public function test_deferred_feedback() {
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);
201         // Check the initial state.
202         $this->check_current_state(question_state::$todo);
203         $this->check_current_mark(null);
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),
208             $this->get_contains_drag_image_home_expectation(3, 1, 2),
209             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
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);
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),
229             $this->get_contains_drag_image_home_expectation(3, 1, 2),
230             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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'));
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),
251             $this->get_contains_drag_image_home_expectation(3, 1, 2),
252             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
264         // Finish the attempt.
265         $this->quba->finish_all_questions();
267         // Verify.
268         $this->check_current_state(question_state::$gradedright);
269         $this->check_current_mark(12);
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),
274             $this->get_contains_drag_image_home_expectation(3, 1, 2),
275             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
286         // Change the right answer a bit.
287         $dd->rightchoices[2] = 1;
289         // Check regrading does not mess anything up.
290         $this->quba->regrade_all_questions();
292         // Verify.
293         $this->check_current_state(question_state::$gradedpartial);
294         $this->check_current_mark(9);
295     }
297     public function test_deferred_feedback_unanswered() {
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);
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),
310             $this->get_contains_drag_image_home_expectation(3, 1, 2),
311             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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);
324         // Save a blank response.
325         $this->process_submission(array('p1' => '', 'p2' => '', 'p3' => '', 'p4' => ''));
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),
333             $this->get_contains_drag_image_home_expectation(3, 1, 2),
334             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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);
347         // Finish the attempt.
348         $this->quba->finish_all_questions();
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),
356             $this->get_contains_drag_image_home_expectation(3, 1, 2),
357             $this->get_contains_drag_image_home_expectation(4, 2, 2));
358     }
360     public function test_deferred_feedback_partial_answer() {
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);
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),
373             $this->get_contains_drag_image_home_expectation(3, 1, 2),
374             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
386         // Save a partial response.
387         $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '', 'p4' => ''));
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),
395             $this->get_contains_drag_image_home_expectation(3, 1, 2),
396             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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(
402                 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
403             $this->get_contains_hidden_expectation(
404                 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
405             $this->get_does_not_contain_correctness_expectation(),
406             $this->get_does_not_contain_feedback_expectation());
408         // Finish the attempt.
409         $this->quba->finish_all_questions();
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),
417             $this->get_contains_drag_image_home_expectation(3, 1, 2),
418             $this->get_contains_drag_image_home_expectation(4, 2, 2),
419             $this->get_contains_partcorrect_expectation());
420     }
422     public function test_interactive_grading() {
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);
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),
443             $this->get_contains_drag_image_home_expectation(3, 1, 2),
444             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
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));
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),
469             $this->get_contains_drag_image_home_expectation(3, 1, 2),
470             $this->get_contains_drag_image_home_expectation(4, 2, 2),
471             $this->get_does_not_contain_submit_button_expectation(),
472             $this->get_contains_try_again_button_expectation(true),
473             $this->get_does_not_contain_correctness_expectation(),
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));
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)));
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));
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),
503             $this->get_contains_drag_image_home_expectation(3, 1, 2),
504             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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(
510                 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
511             $this->get_contains_hidden_expectation(
512                 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
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());
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));
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),
530             $this->get_contains_drag_image_home_expectation(3, 1, 2),
531             $this->get_contains_drag_image_home_expectation(4, 2, 2),
532             $this->get_does_not_contain_submit_button_expectation(),
533             $this->get_contains_try_again_button_expectation(true),
534             $this->get_does_not_contain_correctness_expectation(),
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));
547         // Do try again.
548         $this->process_submission(
549             array('p1' => '1', 'p2' => '', 'p3' => '', 'p4' => '2', '-tryagain' => 1));
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),
557             $this->get_contains_drag_image_home_expectation(3, 1, 2),
558             $this->get_contains_drag_image_home_expectation(4, 2, 2),
559             $this->get_contains_hidden_expectation(
560                 $this->quba->get_field_prefix($this->slot) . 'p1', 1),
561             $this->get_contains_hidden_expectation(
562                 $this->quba->get_field_prefix($this->slot) . 'p2', 0),
563             $this->get_contains_hidden_expectation(
564                 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
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());
574         // Submit the right answer.
575         $this->process_submission(
576             array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2', '-submit' => 1));
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),
584             $this->get_contains_drag_image_home_expectation(3, 1, 2),
585             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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),
594             $this->get_does_not_contain_submit_button_expectation(),
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     }
602     public function test_interactive_correct_no_submit() {
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);
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),
621             $this->get_contains_drag_image_home_expectation(3, 1, 2),
622             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
636         // Save the right answer.
637         $this->process_submission(array('p1' => '1', 'p2' => '2', 'p3' => '1', 'p4' => '2'));
639         // Finish the attempt without clicking check.
640         $this->quba->finish_all_questions();
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),
648             $this->get_contains_drag_image_home_expectation(3, 1, 2),
649             $this->get_contains_drag_image_home_expectation(4, 2, 2),
650             $this->get_does_not_contain_submit_button_expectation(),
651             $this->get_contains_correct_expectation(),
652             $this->get_no_hint_visible_expectation());
654         // Check regrading does not mess anything up.
655         $this->quba->regrade_all_questions();
657         // Verify.
658         $this->check_current_state(question_state::$gradedright);
659         $this->check_current_mark(3);
660     }
662     public function test_interactive_partial_no_submit() {
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);
675         // Check the initial state.
676         $this->check_current_state(question_state::$todo);
677         $this->check_current_mark(null);
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),
682             $this->get_contains_drag_image_home_expectation(3, 1, 2),
683             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
697         // Save the a partially right answer.
698         $this->process_submission(array('p1' => '1', 'p2' => '1', 'p3' => '2', 'p4' => '1'));
700         // Finish the attempt without clicking check.
701         $this->quba->finish_all_questions();
703         // Verify.
704         $this->check_current_state(question_state::$gradedpartial);
705         $this->check_current_mark(1);
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),
710             $this->get_contains_drag_image_home_expectation(3, 1, 2),
711             $this->get_contains_drag_image_home_expectation(4, 2, 2),
712             $this->get_does_not_contain_submit_button_expectation(),
713             $this->get_contains_partcorrect_expectation(),
714             $this->get_no_hint_visible_expectation());
716         // Check regrading does not mess anything up.
717         $this->quba->regrade_all_questions();
719         // Verify.
720         $this->check_current_state(question_state::$gradedpartial);
721         $this->check_current_mark(1);
722     }
724     public function test_interactive_no_right_clears() {
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);
735         // Check the initial state.
736         $this->check_current_state(question_state::$todo);
737         $this->check_current_mark(null);
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),
743             $this->get_contains_drag_image_home_expectation(3, 1, 2),
744             $this->get_contains_drag_image_home_expectation(4, 2, 2),
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());
758         // Save the a completely wrong answer.
759         $this->process_submission(
760             array('p1' => '2', 'p2' => '1', 'p3' => '2', 'p4' => '1', '-submit' => 1));
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),
769             $this->get_contains_drag_image_home_expectation(3, 1, 2),
770             $this->get_contains_drag_image_home_expectation(4, 2, 2),
771             $this->get_does_not_contain_submit_button_expectation(),
772             $this->get_contains_hint_expectation('This is the first hint'));
774         // Do try again.
775         $this->process_submission(
776             array('p1' => '', 'p2' => '', 'p3' => '', 'p4' => '', '-tryagain' => 1));
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),
785             $this->get_contains_drag_image_home_expectation(3, 1, 2),
786             $this->get_contains_drag_image_home_expectation(4, 2, 2),
787             $this->get_contains_hidden_expectation(
788                 $this->quba->get_field_prefix($this->slot) . 'p1', 0),
789             $this->get_contains_hidden_expectation(
790                 $this->quba->get_field_prefix($this->slot) . 'p2', 0),
791             $this->get_contains_hidden_expectation(
792                 $this->quba->get_field_prefix($this->slot) . 'p3', 0),
793             $this->get_contains_hidden_expectation(
794                 $this->quba->get_field_prefix($this->slot) . 'p4', 0),
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     }
801     public function test_display_of_right_answer_when_shuffled() {
803         // Create a drag-and-drop question.
804         $dd = test_question_maker::make_question('ddimageortext');
805         $this->start_attempt_at_question($dd, 'deferredfeedback', 3);
807         // Check the initial state.
808         $this->check_current_state(question_state::$todo);
809         $this->check_current_mark(null);
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());
822         // Save a partial answer.
823         $this->process_submission($dd->get_correct_response());
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());
844         // Finish the attempt.
845         $this->quba->finish_all_questions();
847         // Verify.
848         $this->displayoptions->rightanswer = question_display_options::VISIBLE;
849         $this->assertEquals('Drop zone 1 -> {1. quick} '.
850                 'Drop zone 2 -> {2. fox} '.
851                 'Drop zone 3 -> {3. lazy} '.
852                 'Drop zone 4 -> {4. dog}',
853             $dd->get_right_answer_summary());
854         $this->check_current_state(question_state::$gradedright);
855         $this->check_current_mark(3);
856     }
858     public function test_mixed_lang_rendering() {
860         // Create a mixe drag-and-drop question.
861         $dd = test_question_maker::make_question('ddimageortext', 'mixedlang');
862         $dd->shufflechoices = false;
863         $this->start_attempt_at_question($dd, 'interactive', 1);
865         // Check the initial state.
866         $this->check_current_state(question_state::$todo);
867         $this->check_current_mark(null);
868         $this->check_current_output(
869                 new question_pattern_expectation('~<div class="group1 draghome choice1"><span lang="fr">la</span></div>~'),
870                 new question_pattern_expectation('~<div class="group1 draghome choice2"><span lang="fr">ma</span></div>~')
871         );
872     }