Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace qbehaviour_interactive;
18
 
19
use question_display_options;
20
use question_hint;
21
use question_hint_with_parts;
22
use question_state;
23
 
24
defined('MOODLE_INTERNAL') || die();
25
 
26
global $CFG;
27
require_once(__DIR__ . '/../../../engine/lib.php');
28
require_once(__DIR__ . '/../../../engine/tests/helpers.php');
29
 
30
 
31
/**
32
 * Unit tests for the interactive behaviour.
33
 *
34
 * @package    qbehaviour_interactive
35
 * @copyright  2009 The Open University
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class walkthrough_test extends \qbehaviour_walkthrough_test_base {
39
 
11 efrain 40
    public function test_interactive_feedback_multichoice_right(): void {
1 efrain 41
 
42
        // Create a multichoice single question.
43
        $mc = \test_question_maker::make_a_multichoice_single_question();
44
        $mc->hints = array(
45
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false),
46
            new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
47
        );
48
        $this->start_attempt_at_question($mc, 'interactive');
49
 
50
        $rightindex = $this->get_mc_right_answer_index($mc);
51
        $wrongindex = ($rightindex + 1) % 3;
52
 
53
        // Check the initial state.
54
        $this->check_current_state(question_state::$todo);
55
        $this->check_current_mark(null);
56
        $this->check_current_output(
57
                $this->get_contains_marked_out_of_summary(),
58
                $this->get_contains_question_text_expectation($mc),
59
                $this->get_contains_mc_radio_expectation(0, true, false),
60
                $this->get_contains_mc_radio_expectation(1, true, false),
61
                $this->get_contains_mc_radio_expectation(2, true, false),
62
                $this->get_contains_submit_button_expectation(true),
63
                $this->get_does_not_contain_feedback_expectation(),
64
                $this->get_tries_remaining_expectation(3),
65
                $this->get_no_hint_visible_expectation());
66
 
67
        // Save the wrong answer.
68
        $this->process_submission(array('answer' => $wrongindex));
69
 
70
        // Verify.
71
        $this->check_current_state(question_state::$todo);
72
        $this->check_current_mark(null);
73
        $this->check_current_output(
74
                $this->get_contains_marked_out_of_summary(),
75
                $this->get_contains_mc_radio_expectation($wrongindex, true, true),
76
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
77
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
78
                $this->get_contains_submit_button_expectation(true),
79
                $this->get_does_not_contain_correctness_expectation(),
80
                $this->get_does_not_contain_feedback_expectation(),
81
                $this->get_tries_remaining_expectation(3),
82
                $this->get_no_hint_visible_expectation());
83
 
84
        // Submit the wrong answer.
85
        $this->process_submission(array('answer' => $wrongindex, '-submit' => 1));
86
 
87
        // Verify.
88
        $this->check_current_state(question_state::$todo);
89
        $this->check_current_mark(null);
90
        $this->check_current_output(
91
                $this->get_contains_marked_out_of_summary(),
92
                $this->get_contains_mc_radio_expectation($wrongindex, false, true),
93
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
94
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
95
                $this->get_does_not_contain_submit_button_expectation(),
96
                $this->get_contains_try_again_button_expectation(true),
97
                $this->get_does_not_contain_correctness_expectation(),
98
                new \question_pattern_expectation('/Tries remaining: 2/'),
99
                $this->get_contains_hint_expectation('This is the first hint'));
100
 
101
        // Check that, if we review in this state, the try again button is disabled.
102
        $displayoptions = new question_display_options();
103
        $displayoptions->readonly = true;
104
        $html = $this->quba->render_question($this->slot, $displayoptions);
105
        $this->assert($this->get_contains_try_again_button_expectation(false), $html);
106
 
107
        // Do try again.
108
        $this->process_submission(array('-tryagain' => 1));
109
 
110
        // Verify.
111
        $this->check_current_state(question_state::$todo);
112
        $this->check_current_mark(null);
113
        $this->check_current_output(
114
                $this->get_contains_marked_out_of_summary(),
115
                $this->get_contains_mc_radio_expectation($wrongindex, true, true),
116
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
117
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
118
                $this->get_contains_submit_button_expectation(true),
119
                $this->get_does_not_contain_correctness_expectation(),
120
                $this->get_does_not_contain_feedback_expectation(),
121
                $this->get_tries_remaining_expectation(2),
122
                $this->get_no_hint_visible_expectation());
123
 
124
        // Submit the right answer.
125
        $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
126
 
127
        // Verify.
128
        $this->check_current_state(question_state::$gradedright);
129
        $this->check_current_mark(0.6666667);
130
        $this->check_current_output(
131
                $this->get_contains_mark_summary(0.6666667),
132
                $this->get_contains_mc_radio_expectation($rightindex, false, true),
133
                $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
134
                $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
135
                $this->get_does_not_contain_submit_button_expectation(),
136
                $this->get_contains_correct_expectation(),
137
                $this->get_no_hint_visible_expectation());
138
 
139
        // Finish the attempt - should not need to add a new state.
140
        $numsteps = $this->get_step_count();
141
        $this->quba->finish_all_questions();
142
 
143
        // Verify.
144
        $this->assertEquals($numsteps, $this->get_step_count());
145
        $this->check_current_state(question_state::$gradedright);
146
        $this->check_current_mark(0.6666667);
147
        $this->check_current_output(
148
                $this->get_contains_mark_summary(0.6666667),
149
                $this->get_contains_mc_radio_expectation($rightindex, false, true),
150
                $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
151
                $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
152
                $this->get_contains_correct_expectation(),
153
                $this->get_no_hint_visible_expectation());
154
 
155
        // Process a manual comment.
156
        $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
157
 
158
        // Verify.
159
        $this->check_current_state(question_state::$mangrpartial);
160
        $this->check_current_mark(0.5);
161
        $this->check_current_output(
162
                $this->get_contains_mark_summary(0.5),
163
                $this->get_contains_partcorrect_expectation(),
164
                new \question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
165
 
166
        // Check regrading does not mess anything up.
167
        $this->quba->regrade_all_questions();
168
 
169
        // Verify.
170
        $this->check_current_state(question_state::$mangrpartial);
171
        $this->check_current_mark(0.5);
172
        $this->check_current_output(
173
                $this->get_contains_mark_summary(0.5),
174
                $this->get_contains_partcorrect_expectation());
175
 
176
        $autogradedstep = $this->get_step($this->get_step_count() - 2);
177
        $this->assertEqualsWithDelta($autogradedstep->get_fraction(), 0.6666667, 0.0000001);
178
    }
179
 
11 efrain 180
    public function test_interactive_finish_when_try_again_showing(): void {
1 efrain 181
 
182
        // Create a multichoice single question.
183
        $mc = \test_question_maker::make_a_multichoice_single_question();
184
        $mc->showstandardinstruction = true;
185
        $mc->hints = array(
186
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false),
187
        );
188
        $this->start_attempt_at_question($mc, 'interactive');
189
 
190
        $rightindex = $this->get_mc_right_answer_index($mc);
191
        $wrongindex = ($rightindex + 1) % 3;
192
 
193
        // Check the initial state.
194
        $this->check_current_state(question_state::$todo);
195
        $this->check_current_mark(null);
196
        $this->check_current_output(
197
                $this->get_contains_marked_out_of_summary(),
198
                $this->get_contains_question_text_expectation($mc),
199
                $this->get_contains_mc_radio_expectation(0, true, false),
200
                $this->get_contains_mc_radio_expectation(1, true, false),
201
                $this->get_contains_mc_radio_expectation(2, true, false),
202
                $this->get_contains_submit_button_expectation(true),
203
                $this->get_does_not_contain_feedback_expectation(),
204
                $this->get_tries_remaining_expectation(2),
205
                $this->get_no_hint_visible_expectation(),
206
                new \question_pattern_expectation('/' .
207
                        preg_quote(get_string('selectone', 'qtype_multichoice'), '/') . '/'));
208
 
209
        // Submit the wrong answer.
210
        $this->process_submission(array('answer' => $wrongindex, '-submit' => 1));
211
 
212
        // Verify.
213
        $this->check_current_state(question_state::$todo);
214
        $this->check_current_mark(null);
215
        $this->check_current_output(
216
                $this->get_contains_marked_out_of_summary(),
217
                $this->get_contains_mc_radio_expectation($wrongindex, false, true),
218
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
219
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
220
                $this->get_does_not_contain_submit_button_expectation(),
221
                $this->get_contains_try_again_button_expectation(true),
222
                $this->get_does_not_contain_correctness_expectation(),
223
                new \question_pattern_expectation('/Tries remaining: 1/'),
224
                $this->get_contains_hint_expectation('This is the first hint'));
225
 
226
        // Finish the attempt.
227
        $this->quba->finish_all_questions();
228
 
229
        // Verify.
230
        $this->check_current_state(question_state::$gradedwrong);
231
        $this->check_current_mark(0);
232
        $this->check_current_output(
233
                $this->get_contains_mark_summary(0),
234
                $this->get_contains_mc_radio_expectation($wrongindex, false, true),
235
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
236
                $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
237
                $this->get_contains_incorrect_expectation(),
238
                $this->get_no_hint_visible_expectation());
239
    }
240
 
11 efrain 241
    public function test_interactive_shortanswer_try_to_submit_blank(): void {
1 efrain 242
 
243
        // Create a short answer question.
244
        $sa = \test_question_maker::make_question('shortanswer');
245
        $sa->hints = array(
246
            new question_hint(0, 'This is the first hint.', FORMAT_HTML),
247
            new question_hint(0, 'This is the second hint.', FORMAT_HTML),
248
        );
249
        $this->start_attempt_at_question($sa, 'interactive');
250
 
251
        // Check the initial state.
252
        $this->check_current_state(question_state::$todo);
253
        $this->check_current_mark(null);
254
        $this->check_current_output(
255
                $this->get_contains_marked_out_of_summary(),
256
                $this->get_contains_submit_button_expectation(true),
257
                $this->get_does_not_contain_feedback_expectation(),
258
                $this->get_does_not_contain_validation_error_expectation(),
259
                $this->get_does_not_contain_try_again_button_expectation(),
260
                $this->get_no_hint_visible_expectation());
261
 
262
        // Submit blank.
263
        $this->process_submission(array('-submit' => 1, 'answer' => ''));
264
 
265
        // Verify.
266
        $this->check_current_state(question_state::$invalid);
267
        $this->check_current_mark(null);
268
        $this->check_current_output(
269
                $this->get_contains_marked_out_of_summary(),
270
                $this->get_contains_submit_button_expectation(true),
271
                $this->get_does_not_contain_feedback_expectation(),
272
                $this->get_contains_validation_error_expectation(),
273
                $this->get_does_not_contain_try_again_button_expectation(),
274
                $this->get_no_hint_visible_expectation());
275
 
276
        // Now get it wrong.
277
        $this->process_submission(array('-submit' => 1, 'answer' => 'newt'));
278
 
279
        // Verify.
280
        $this->check_current_state(question_state::$todo);
281
        $this->check_current_mark(null);
282
        $this->check_current_output(
283
                $this->get_contains_marked_out_of_summary(),
284
                $this->get_does_not_contain_submit_button_expectation(),
285
                $this->get_does_not_contain_validation_error_expectation(),
286
                $this->get_contains_try_again_button_expectation(true),
287
                new \question_pattern_expectation('/Tries remaining: 2/'),
288
                $this->get_contains_hint_expectation('This is the first hint'));
289
        $this->assertEquals('newt',
290
                $this->quba->get_response_summary($this->slot));
291
 
292
        // Try again.
293
        $this->process_submission(array('-tryagain' => 1));
294
 
295
        // Verify.
296
        $this->check_current_state(question_state::$todo);
297
        $this->check_current_mark(null);
298
        $this->check_current_output(
299
                $this->get_contains_marked_out_of_summary(),
300
                $this->get_contains_submit_button_expectation(true),
301
                $this->get_does_not_contain_feedback_expectation(),
302
                $this->get_does_not_contain_validation_error_expectation(),
303
                $this->get_does_not_contain_try_again_button_expectation(),
304
                $this->get_no_hint_visible_expectation());
305
 
306
        // Now submit blank again.
307
        $this->process_submission(array('-submit' => 1, 'answer' => ''));
308
 
309
        // Verify.
310
        $this->check_current_state(question_state::$invalid);
311
        $this->check_current_mark(null);
312
        $this->check_current_output(
313
                $this->get_contains_marked_out_of_summary(),
314
                $this->get_contains_submit_button_expectation(true),
315
                $this->get_does_not_contain_feedback_expectation(),
316
                $this->get_contains_validation_error_expectation(),
317
                $this->get_does_not_contain_try_again_button_expectation(),
318
                $this->get_no_hint_visible_expectation());
319
 
320
        // Now get it right.
321
        $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
322
 
323
        // Verify.
324
        $this->check_current_state(question_state::$gradedright);
325
        $this->check_current_mark(0.6666667);
326
        $this->check_current_output(
327
                $this->get_contains_mark_summary(0.6666667),
328
                $this->get_does_not_contain_submit_button_expectation(),
329
                $this->get_contains_correct_expectation(),
330
                $this->get_does_not_contain_validation_error_expectation(),
331
                $this->get_no_hint_visible_expectation());
332
        $this->assertEquals('frog',
333
                $this->quba->get_response_summary($this->slot));
334
    }
335
 
11 efrain 336
    public function test_interactive_feedback_multichoice_multiple_reset(): void {
1 efrain 337
 
338
        // Create a multichoice multiple question.
339
        $mc = \test_question_maker::make_a_multichoice_multi_question();
340
        $mc->showstandardinstruction = true;
341
        $mc->hints = array(
342
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
343
            new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
344
        );
345
        $this->start_attempt_at_question($mc, 'interactive', 2);
346
 
347
        $right = array_keys($mc->get_correct_response());
348
        $wrong = array_diff(array('choice0', 'choice1', 'choice2', 'choice3'), $right);
349
        $wrong = array_values(array_diff(
350
                array('choice0', 'choice1', 'choice2', 'choice3'), $right));
351
 
352
        // Check the initial state.
353
        $this->check_current_state(question_state::$todo);
354
        $this->check_current_mark(null);
355
        $this->check_current_output(
356
                $this->get_contains_marked_out_of_summary(),
357
                $this->get_contains_question_text_expectation($mc),
358
                $this->get_contains_mc_checkbox_expectation('choice0', true, false),
359
                $this->get_contains_mc_checkbox_expectation('choice1', true, false),
360
                $this->get_contains_mc_checkbox_expectation('choice2', true, false),
361
                $this->get_contains_mc_checkbox_expectation('choice3', true, false),
362
                $this->get_contains_submit_button_expectation(true),
363
                $this->get_does_not_contain_feedback_expectation(),
364
                $this->get_does_not_contain_num_parts_correct(),
365
                $this->get_tries_remaining_expectation(3),
366
                $this->get_no_hint_visible_expectation(),
367
                new \question_pattern_expectation('/' .
368
                        preg_quote(get_string('selectmulti', 'qtype_multichoice'), '/') . '/'));
369
 
370
        // Submit an answer with one right, and one wrong.
371
        $this->process_submission(array($right[0] => 1, $wrong[0] => 1, '-submit' => 1));
372
 
373
        // Verify.
374
        $this->check_current_state(question_state::$todo);
375
        $this->check_current_mark(null);
376
        $this->check_current_output(
377
                $this->get_contains_marked_out_of_summary(),
378
                $this->get_contains_mc_checkbox_expectation($right[0], false, true),
379
                $this->get_contains_mc_checkbox_expectation($right[1], false, false),
380
                $this->get_contains_mc_checkbox_expectation($wrong[0], false, true),
381
                $this->get_contains_mc_checkbox_expectation($wrong[1], false, false),
382
                $this->get_does_not_contain_submit_button_expectation(),
383
                $this->get_contains_try_again_button_expectation(true),
384
                $this->get_does_not_contain_correctness_expectation(),
385
                new \question_pattern_expectation('/Tries remaining: 2/'),
386
                $this->get_contains_hint_expectation('This is the first hint'),
387
                $this->get_contains_num_parts_correct(1),
388
                $this->get_contains_standard_incorrect_combined_feedback_expectation(),
389
                $this->get_contains_hidden_expectation(
390
                        $this->quba->get_field_prefix($this->slot) . $right[0], '1'),
391
                $this->get_does_not_contain_hidden_expectation(
392
                        $this->quba->get_field_prefix($this->slot) . $right[1]),
393
                $this->get_contains_hidden_expectation(
394
                        $this->quba->get_field_prefix($this->slot) . $wrong[0], '0'),
395
                $this->get_does_not_contain_hidden_expectation(
396
                        $this->quba->get_field_prefix($this->slot) . $wrong[1]));
397
 
398
        // Do try again.
399
        $this->process_submission(array($right[0] => 1, '-tryagain' => 1));
400
 
401
        // Verify.
402
        $this->check_current_state(question_state::$todo);
403
        $this->check_current_mark(null);
404
        $this->check_current_output(
405
                $this->get_contains_marked_out_of_summary(),
406
                $this->get_contains_mc_checkbox_expectation($right[0], true, true),
407
                $this->get_contains_mc_checkbox_expectation($right[1], true, false),
408
                $this->get_contains_mc_checkbox_expectation($wrong[0], true, false),
409
                $this->get_contains_mc_checkbox_expectation($wrong[1], true, false),
410
                $this->get_contains_submit_button_expectation(true),
411
                $this->get_does_not_contain_correctness_expectation(),
412
                $this->get_does_not_contain_feedback_expectation(),
413
                $this->get_tries_remaining_expectation(2),
414
                $this->get_no_hint_visible_expectation());
415
    }
416
 
11 efrain 417
    public function test_interactive_regrade_changing_num_tries_leaving_open(): void {
1 efrain 418
        // Create a multichoice multiple question.
419
        $q = \test_question_maker::make_question('shortanswer');
420
        $q->hints = array(
421
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
422
            new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
423
        );
424
        $this->start_attempt_at_question($q, 'interactive', 3);
425
 
426
        // Check the initial state.
427
        $this->check_current_state(question_state::$todo);
428
        $this->check_current_mark(null);
429
        $this->check_current_output(
430
                $this->get_tries_remaining_expectation(3));
431
 
432
        // Submit the right answer.
433
        $this->process_submission(array('answer' => 'frog', '-submit' => 1));
434
 
435
        // Verify.
436
        $this->check_current_state(question_state::$gradedright);
437
        $this->check_current_mark(3);
438
 
439
        // Now change the quiestion so that answer is only partially right, and regrade.
440
        $q->answers[13]->fraction = 0.6666667;
441
        $q->answers[14]->fraction = 1;
442
 
443
        $this->quba->regrade_all_questions(false);
444
 
445
        // Verify.
446
        $this->check_current_state(question_state::$todo);
447
        $this->check_current_mark(null);
448
    }
449
 
11 efrain 450
    public function test_interactive_regrade_changing_num_tries_finished(): void {
1 efrain 451
        // Create a multichoice multiple question.
452
        $q = \test_question_maker::make_question('shortanswer');
453
        $q->hints = array(
454
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
455
            new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
456
        );
457
        $this->start_attempt_at_question($q, 'interactive', 3);
458
 
459
        // Check the initial state.
460
        $this->check_current_state(question_state::$todo);
461
        $this->check_current_mark(null);
462
        $this->check_current_output(
463
                $this->get_tries_remaining_expectation(3));
464
 
465
        // Submit the right answer.
466
        $this->process_submission(array('answer' => 'frog', '-submit' => 1));
467
 
468
        // Verify.
469
        $this->check_current_state(question_state::$gradedright);
470
        $this->check_current_mark(3);
471
 
472
        // Now change the quiestion so that answer is only partially right, and regrade.
473
        $q->answers[13]->fraction = 0.6666667;
474
        $q->answers[14]->fraction = 1;
475
 
476
        $this->quba->regrade_all_questions(true);
477
 
478
        // Verify.
479
        $this->check_current_state(question_state::$gradedpartial);
480
        // TODO I don't think 1 is the right fraction here. However, it is what
481
        // you get attempting a question like this without regrading being involved,
482
        // and I am currently interested in testing regrading here.
483
        $this->check_current_mark(1);
484
    }
485
 
11 efrain 486
    public function test_review_of_interactive_questions_before_finished(): void {
1 efrain 487
        // Create a multichoice multiple question.
488
        $q = \test_question_maker::make_question('shortanswer');
489
        $q->hints = array(
490
                new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
491
                new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
492
        );
493
        $this->start_attempt_at_question($q, 'interactive', 3);
494
 
495
        // Check the initial state.
496
        $this->check_current_state(question_state::$todo);
497
        $this->check_current_mark(null);
498
        $this->check_current_output(
499
                $this->get_contains_submit_button_expectation(true),
500
                $this->get_does_not_contain_feedback_expectation(),
501
                $this->get_tries_remaining_expectation(3),
502
                $this->get_does_not_contain_try_again_button_expectation());
503
 
504
        // Now check what the teacher sees when they review the question.
505
        $this->displayoptions->readonly = true;
506
        $this->check_current_output(
507
                $this->get_contains_submit_button_expectation(false),
508
                $this->get_does_not_contain_feedback_expectation(),
509
                $this->get_tries_remaining_expectation(3),
510
                $this->get_does_not_contain_try_again_button_expectation());
511
        $this->displayoptions->readonly = false;
512
 
513
        // Submit a wrong answer.
514
        $this->process_submission(array('answer' => 'cat', '-submit' => 1));
515
 
516
        // Check the Try again button now shows up correctly.
517
        $this->check_current_state(question_state::$todo);
518
        $this->check_current_mark(null);
519
        $this->check_current_output(
520
                $this->get_does_not_contain_submit_button_expectation(),
521
                $this->get_contains_hint_expectation('This is the first hint.'),
522
                $this->get_tries_remaining_expectation(2),
523
                $this->get_contains_try_again_button_expectation(true));
524
 
525
        // And check that a disabled Try again button shows up when the question is reviewed.
526
        $this->displayoptions->readonly = true;
527
        $this->check_current_output(
528
                $this->get_does_not_contain_submit_button_expectation(),
529
                $this->get_contains_hint_expectation('This is the first hint.'),
530
                $this->get_tries_remaining_expectation(2),
531
                $this->get_contains_try_again_button_expectation(false));
532
    }
533
}