19
19
defined ('MOODLE_INTERNAL ' ) || die ();
20
20
21
21
global $ CFG ;
22
+ require_once ($ CFG ->dirroot . '/question/engine/tests/helpers.php ' );
22
23
require_once ($ CFG ->dirroot . '/question/type/questionpy/question.php ' );
23
24
24
25
use coding_exception ;
25
26
use PHPUnit \Framework \MockObject \Stub ;
26
27
use qtype_questionpy \api \api ;
28
+ use qtype_questionpy \constants ;
27
29
use qtype_questionpy_question ;
28
30
use question_attempt ;
31
+ use question_attempt_step ;
32
+ use testable_question_attempt ;
29
33
30
34
/**
31
35
* Unit tests for {@see question_ui_renderer}.
@@ -80,7 +84,7 @@ public function test_should_hide_inline_feedback(): void {
80
84
<div xmlns="http://www.w3.org/1999/xhtml">
81
85
<span>No feedback</span>
82
86
</div>
83
- EXPECTED , $ result );
87
+ EXPECTED , $ result-> html );
84
88
}
85
89
86
90
/**
@@ -104,7 +108,7 @@ public function test_should_show_inline_feedback(): void {
104
108
<span>General feedback</span>
105
109
<span>Specific feedback</span>
106
110
</div>
107
- EXPECTED , $ result );
111
+ EXPECTED , $ result-> html );
108
112
}
109
113
110
114
/**
@@ -122,27 +126,27 @@ public function test_should_mangle_names(): void {
122
126
$ result = $ ui ->render ();
123
127
124
128
$ this ->assert_html_string_equals_html_string (<<<EXPECTED
125
- <div xmlns="http://www.w3.org/1999/xhtml" id="mangled:my_div ">
126
- <datalist id="mangled:my_list ">
129
+ <div xmlns="http://www.w3.org/1999/xhtml" id="q1:1_my_div ">
130
+ <datalist id="q1:1_my_list ">
127
131
<option>42</option>
128
132
</datalist>
129
- <label>Wrapping label <input class="form-control qpy-input" name="mangled:my_number "
130
- type="number" list="mangled:my_list "/></label>
131
- <label for="mangled:my_select ">Separate label</label>
132
- <select class="form-control qpy-input" id="mangled:my_select " name="mangled:my_select ">
133
+ <label>Wrapping label <input class="form-control qpy-input" name="q1:1_my_number "
134
+ type="number" list="q1:1_my_list "/></label>
135
+ <label for="q1:1_my_select ">Separate label</label>
136
+ <select class="form-control qpy-input" id="q1:1_my_select " name="q1:1_my_select ">
133
137
<option value="1">One</option>
134
138
<option value="2">Two</option>
135
139
</select>
136
- <input class="qpy-input" type="radio" name="mangled:my_radio " value="1"/>
137
- <input class="qpy-input" type="radio" name="mangled:my_radio " value="2"/>
138
- <textarea class="form-control qpy-input" name="mangled:my_text "/>
139
- <button class="btn btn-primary qpy-input" name="mangled:my_button ">Click me!</button>
140
- <map name="mangled:my_map ">
140
+ <input class="qpy-input" type="radio" name="q1:1_my_radio " value="1"/>
141
+ <input class="qpy-input" type="radio" name="q1:1_my_radio " value="2"/>
142
+ <textarea class="form-control qpy-input" name="q1:1_my_text "/>
143
+ <button class="btn btn-primary qpy-input" name="q1:1_my_button ">Click me!</button>
144
+ <map name="q1:1_my_map ">
141
145
<area shape="circle" coords="1, 2, 3"/>
142
146
</map>
143
- <img src="https://picsum.photos/200/300" usemap="#mangled:my_map "/>
147
+ <img src="https://picsum.photos/200/300" usemap="#q1:1_my_map "/>
144
148
</div>
145
- EXPECTED , $ result );
149
+ EXPECTED , $ result-> html );
146
150
}
147
151
148
152
/**
@@ -179,7 +183,7 @@ public function test_should_shuffle_correctly_and_replace_indices(): void {
179
183
</div>
180
184
</div>
181
185
</div>
182
- EXPECTED , $ result );
186
+ EXPECTED , $ result-> html );
183
187
}
184
188
185
189
/**
@@ -195,7 +199,7 @@ public function test_should_shuffle_the_same_way_in_same_attempt(): void {
195
199
$ firstresult = (new question_ui_renderer ($ input , [], new \question_display_options (), $ qa ))->render ();
196
200
for ($ i = 0 ; $ i < 10 ; $ i ++) {
197
201
$ result = (new question_ui_renderer ($ input , [], new \question_display_options (), $ qa ))->render ();
198
- $ this ->assertEquals ($ firstresult , $ result );
202
+ $ this ->assertEquals ($ firstresult-> html , $ result-> html );
199
203
}
200
204
}
201
205
@@ -225,7 +229,7 @@ public function test_should_resolve_placeholders(): void {
225
229
<span>Plain parameter: Value of param <b>one</b>.<script>'Oh no, danger!'</script>
226
230
</span>
227
231
</div>
228
- EXPECTED , $ result );
232
+ EXPECTED , $ result-> html );
229
233
}
230
234
231
235
/**
@@ -257,7 +261,7 @@ public function test_should_correctly_handle_broken_html_in_placeholder_expansio
257
261
<span>Noclean parameter: <format-float>123</format-float><unknown-tag></unknown-tag><div>unclosed</div></span>
258
262
<span>Plain parameter: <qpy:format-float>123</qpy:format-float><unknown-tag></unknown-tag><div>unclosed</span>
259
263
</div>
260
- EXPECTED , $ result );
264
+ EXPECTED , $ result-> html );
261
265
// phpcs:enable moodle.Files.LineLength.TooLong
262
266
}
263
267
@@ -283,7 +287,7 @@ public function test_should_remove_placeholders_when_no_corresponding_value(): v
283
287
<span>Noclean parameter: </span>
284
288
<span>Plain parameter: </span>
285
289
</div>
286
- EXPECTED , $ result );
290
+ EXPECTED , $ result-> html );
287
291
}
288
292
289
293
/**
@@ -312,7 +316,7 @@ public function test_should_soften_validations(): void {
312
316
data-qpy_minlength="5" data-qpy_maxlength="10"
313
317
aria-valuemin="17" data-qpy_min="17" aria-valuemax="42" data-qpy_max="42"/>
314
318
</div>
315
- EXPECTED , $ result );
319
+ EXPECTED , $ result-> html );
316
320
}
317
321
318
322
/**
@@ -338,7 +342,7 @@ public function test_should_defuse_buttons(): void {
338
342
<input class="btn btn-primary qpy-input" type="button" value="Reset"/>
339
343
<input class="btn btn-primary qpy-input" type="button" value="Button"/>
340
344
</div>
341
- EXPECTED , $ result );
345
+ EXPECTED , $ result-> html );
342
346
}
343
347
344
348
/**
@@ -363,7 +367,7 @@ public function test_should_remove_element_with_if_role_attribute(): void {
363
367
364
368
$ this ->assert_html_string_equals_html_string (<<<EXPECTED
365
369
<div xmlns="http://www.w3.org/1999/xhtml"></div>
366
- EXPECTED , $ result );
370
+ EXPECTED , $ result-> html );
367
371
}
368
372
369
373
/**
@@ -395,7 +399,7 @@ public function test_should_not_remove_element_with_if_role_attribute(): void {
395
399
<div>You're a proctor!</div>
396
400
<div>You're any of the above!</div>
397
401
</div>
398
- EXPECTED , $ result );
402
+ EXPECTED , $ result-> html );
399
403
}
400
404
401
405
/**
@@ -421,7 +425,7 @@ public function test_should_format_floats_in_en(): void {
421
425
Pad with zeros: 1.10000
422
426
Strip zeros: 1.1
423
427
</div>
424
- EXPECTED , $ result );
428
+ EXPECTED , $ result-> html );
425
429
}
426
430
427
431
/**
@@ -444,7 +448,7 @@ public function test_should_replace_qpy_urls(): void {
444
448
static link: <a href="https://www.example.com/moodle/pluginfile.php//qtype_questionpy/static/deadbeef/local/minimal_example/path1/path2/filename.txt">https://www.example.com/moodle/pluginfile.php//qtype_questionpy/static/deadbeef/local/minimal_example/path1/path2/filename.txt</a>
445
449
minimal path: <a href="https://www.example.com/moodle/pluginfile.php//qtype_questionpy/static/deadbeef/local/minimal_example/f">https://www.example.com/moodle/pluginfile.php//qtype_questionpy/static/deadbeef/local/minimal_example/f</a>
446
450
</div>
447
- EXPECTED , $ result );
451
+ EXPECTED , $ result-> html );
448
452
// phpcs:enable moodle.Files.LineLength.MaxExceeded
449
453
}
450
454
@@ -457,44 +461,41 @@ public function test_should_replace_qpy_urls(): void {
457
461
*/
458
462
public function test_should_correctly_fill_data (): void {
459
463
$ input = file_get_contents (__DIR__ . '/question_uis/input-values.xhtml ' );
460
- $ qa = $ this ->create_question_attempt_stub ('deadbeef ' );
461
- $ newvalues = [
464
+ $ qa = $ this ->create_question_attempt_stub ('deadbeef ' , lastresponse: [
462
465
'my_text ' => 'new ' ,
463
466
'my_checkbox_value ' => 'value ' ,
464
467
'my_checkbox_on ' => 'on ' ,
465
468
'my_radio ' => 'value1 ' ,
466
469
'my_select ' => 'value3 ' ,
467
470
'my_hidden ' => 'new ' ,
468
471
'my_button ' => 'should be ignored ' ,
469
- ];
470
- $ qa ->method ('get_last_qt_var ' )
471
- ->willReturnCallback (fn ($ name ) => $ newvalues [$ name ]);
472
+ ]);
472
473
473
474
$ ui = new question_ui_renderer ($ input , [], new \question_display_options (), $ qa );
474
475
$ result = $ ui ->render ();
475
476
476
477
$ this ->assert_html_string_equals_html_string (<<<EXPECTED
477
- <div xmlns="http://www.w3.org/1999/xhtml" id="mangled:my_div ">
478
- <input class="form-control qpy-input" type="text" name="mangled:my_text " value="new"/>
478
+ <div xmlns="http://www.w3.org/1999/xhtml" id="q1:1_my_div ">
479
+ <input class="form-control qpy-input" type="text" name="q1:1_my_text " value="new"/>
479
480
480
- <input class="qpy-input" type="checkbox" name="mangled:my_checkbox_value " value="value" checked="checked"/>
481
- <input class="qpy-input" type="checkbox" name="mangled:my_checkbox_on " checked="checked"/>
481
+ <input class="qpy-input" type="checkbox" name="q1:1_my_checkbox_value " value="value" checked="checked"/>
482
+ <input class="qpy-input" type="checkbox" name="q1:1_my_checkbox_on " checked="checked"/>
482
483
483
- <input class="qpy-input" type="radio" name="mangled:my_radio " value="value1" checked="checked"/>
484
- <input class="qpy-input" type="radio" name="mangled:my_radio " value="value2"/>
484
+ <input class="qpy-input" type="radio" name="q1:1_my_radio " value="value1" checked="checked"/>
485
+ <input class="qpy-input" type="radio" name="q1:1_my_radio " value="value2"/>
485
486
486
- <select class="form-control qpy-input" name="mangled:my_select ">
487
+ <select class="form-control qpy-input" name="q1:1_my_select ">
487
488
<option value="value1"/>
488
489
<option value="value2"/>
489
490
<option value="value3" selected="selected"/>
490
491
</select>
491
492
492
- <input class="form-control qpy-input" type="hidden" name="mangled:my_hidden " value="new"/>
493
+ <input class="form-control qpy-input" type="hidden" name="q1:1_my_hidden " value="new"/>
493
494
494
- <input class="btn btn-primary qpy-input" name="mangled:my_button " type="button" value="value1"/>
495
- <input class="btn btn-primary qpy-input" name="mangled:my_button " type="button" value="value2"/>
495
+ <input class="btn btn-primary qpy-input" name="q1:1_my_button " type="button" value="value1"/>
496
+ <input class="btn btn-primary qpy-input" name="q1:1_my_button " type="button" value="value2"/>
496
497
</div>
497
- EXPECTED , $ result );
498
+ EXPECTED , $ result-> html );
498
499
}
499
500
500
501
/**
@@ -506,46 +507,49 @@ public function test_should_correctly_fill_data(): void {
506
507
*/
507
508
public function test_should_add_fallback_option_to_select_when_value_isnt_present (): void {
508
509
$ input = file_get_contents (__DIR__ . '/question_uis/select.xhtml ' );
509
- $ qa = $ this ->create_question_attempt_stub ('deadbeef ' );
510
- $ qa -> method ( ' get_last_qt_var ' )
511
- -> willReturn ( ' something ' );
510
+ $ qa = $ this ->create_question_attempt_stub ('deadbeef ' , lastresponse: [
511
+ ' my_select ' => ' something ' ,
512
+ ] );
512
513
513
514
$ ui = new question_ui_renderer ($ input , [], new \question_display_options (), $ qa );
514
515
$ result = $ ui ->render ();
515
516
516
517
$ this ->assert_html_string_equals_html_string (<<<EXPECTED
517
518
<div xmlns="http://www.w3.org/1999/xhtml" >
518
- <select class="form-control qpy-input" name="mangled:my_select ">
519
+ <select class="form-control qpy-input" name="q1:1_my_select ">
519
520
<option value="value1"/>
520
521
<option value="value2"/>
521
522
<option value="value3"/>
522
523
<option value="something" selected="selected">(the selected option is no longer available)</option>
523
524
</select>
524
525
</div>
525
- EXPECTED , $ result );
526
+ EXPECTED , $ result-> html );
526
527
}
527
528
528
529
/**
529
530
* Creates a stub question attempt which should fulfill the needs of most tests.
530
531
*
531
532
* @param string|null $packagehash explicit package hash. Random if unset.
532
533
* @param int|null $id explicit attempt database id. Random if unset.
534
+ * @param array $lastresponse last response submitted in the attempt
533
535
* @return question_attempt&Stub
536
+ * @throws coding_exception
534
537
*/
535
- private function create_question_attempt_stub (?string $ packagehash = null , ?int $ id = null ): question_attempt {
538
+ private function create_question_attempt_stub (?string $ packagehash = null , ?int $ id = null ,
539
+ array $ lastresponse = []): question_attempt {
536
540
$ packagehash ??= hash ('sha256 ' , random_string (64 ));
537
541
$ id ??= mt_rand ();
538
542
$ question = new qtype_questionpy_question ($ packagehash , '{} ' , null , $ this ->createStub (api::class));
539
543
540
- $ qa = $ this -> createStub (question_attempt::class);
541
- $ qa -> method ( ' get_database_id ' )
542
- -> willReturn ( $ id );
543
- $ qa -> method ( ' get_question ' )
544
- -> willReturn ($ question );
545
- $ qa ->method ( ' get_qt_field_name ' )
546
- -> willReturnCallback ( function ( $ name ) {
547
- return " mangled: $ name " ;
548
- });
544
+ $ step = new question_attempt_step ( array_merge ( $ lastresponse , [
545
+ constants:: QT_VAR_RESPONSE_MARKER => '' ,
546
+ ]) );
547
+
548
+ $ qa = new testable_question_attempt ($ question, 1 );
549
+ $ qa ->set_database_id ( $ id );
550
+ $ qa -> set_slot ( 1 );
551
+ $ qa -> add_step ( $ step ) ;
552
+
549
553
return $ qa ;
550
554
}
551
555
}
0 commit comments