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
/**
18
 * Unit tests for the Moodle XML format.
19
 *
20
 * @package    qformat_xml
21
 * @copyright  2010 The Open University
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace qformat_xml;
26
 
27
use qformat_xml;
28
use qtype_numerical_answer;
29
use question_answer;
30
use question_bank;
31
use question_check_specified_fields_expectation;
32
use question_hint;
33
use question_hint_with_parts;
34
 
35
defined('MOODLE_INTERNAL') || die();
36
 
37
global $CFG;
38
require_once($CFG->libdir . '/questionlib.php');
39
require_once($CFG->dirroot . '/question/format/xml/format.php');
40
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
41
 
42
/**
43
 * Unit tests for the matching question definition class.
44
 *
45
 * @package    qformat_xml
46
 * @copyright  2009 The Open University
47
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
48
 */
49
class xmlformat_test extends \question_testcase {
50
    public function make_test_question() {
51
        global $USER;
52
        $q = new \stdClass();
53
        $q->id = 0;
54
        $q->contextid = 0;
55
        $q->idnumber = null;
56
        $q->category = 0;
57
        $q->parent = 0;
58
        $q->questiontextformat = FORMAT_HTML;
59
        $q->generalfeedbackformat = FORMAT_HTML;
60
        $q->defaultmark = 1;
61
        $q->penalty = 0.3333333;
62
        $q->length = 1;
63
        $q->stamp = make_unique_id_code();
64
        $q->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
65
        $q->timecreated = time();
66
        $q->timemodified = time();
67
        $q->createdby = $USER->id;
68
        $q->modifiedby = $USER->id;
69
        return $q;
70
    }
71
 
72
    /**
73
     * The data the XML import format sends to save_question is not exactly
74
     * the same as the data returned from the editing form, so this method
75
     * makes necessary changes to the return value of
76
     * \test_question_maker::get_question_form_data so that the tests can work.
77
     * @param object $expectedq as returned by get_question_form_data.
78
     * @return object one more likely to match the return value of import_...().
79
     */
80
    public function remove_irrelevant_form_data_fields($expectedq) {
81
        return $this->itemid_to_files($expectedq);
82
    }
83
 
84
    /**
85
     * Becuase XML import uses a files array instead of an itemid integer to
86
     * handle saving files with a question, we need to covert the output of
87
     * \test_question_maker::get_question_form_data to match. This method recursively
88
     * replaces all array elements with key itemid with an array entry with
89
     * key files and value an empty array.
90
     *
91
     * @param mixed $var any data structure.
92
     * @return mixed an equivalent structure with the relacements made.
93
     */
94
    protected function itemid_to_files($var) {
95
        if (is_object($var)) {
96
            $newvar = new \stdClass();
97
            foreach (get_object_vars($var) as $field => $value) {
98
                $newvar->$field = $this->itemid_to_files($value);
99
            }
100
 
101
        } else if (is_array($var)) {
102
            $newvar = array();
103
            foreach ($var as $index => $value) {
104
                if ($index === 'itemid') {
105
                    $newvar['files'] = array();
106
                } else {
107
                    $newvar[$index] = $this->itemid_to_files($value);
108
                }
109
            }
110
 
111
        } else {
112
            $newvar = $var;
113
        }
114
 
115
        return $newvar;
116
    }
117
 
11 efrain 118
    public function test_xml_escape_simple_input_not_escaped(): void {
1 efrain 119
        $exporter = new qformat_xml();
120
        $string = 'Nothing funny here. Even if we go to a café or to 日本.';
121
        $this->assertEquals($string, $exporter->xml_escape($string));
122
    }
123
 
11 efrain 124
    public function test_xml_escape_html_wrapped_in_cdata(): void {
1 efrain 125
        $exporter = new qformat_xml();
126
        $string = '<p>Nothing <b>funny<b> here. Even if we go to a café or to 日本.</p>';
127
        $this->assertEquals('<![CDATA[' . $string . ']]>', $exporter->xml_escape($string));
128
    }
129
 
11 efrain 130
    public function test_xml_escape_script_tag_handled_ok(): void {
1 efrain 131
        $exporter = new qformat_xml();
132
        $input = '<script><![CDATA[alert(1<2);]]></script>';
133
        $expected = '<![CDATA[<script><![CDATA[alert(1<2);]]]]><![CDATA[></script>]]>';
134
        $this->assertEquals($expected, $exporter->xml_escape($input));
135
 
136
        // Check that parsing the expected result does give the input again.
137
        $parsed = simplexml_load_string('<div>' . $expected . '</div>');
138
        $this->assertEquals($input, $parsed->xpath('//div')[0]);
139
    }
140
 
11 efrain 141
    public function test_xml_escape_code_that_looks_like_cdata_end_ok(): void {
1 efrain 142
        $exporter = new qformat_xml();
143
        $input = "if (x[[0]]>a) print('hah');";
144
        $expected = "<![CDATA[if (x[[0]]]]><![CDATA[>a) print('hah');]]>";
145
        $this->assertEquals($expected, $exporter->xml_escape($input));
146
 
147
        // Check that parsing the expected result does give the input again.
148
        $parsed = simplexml_load_string('<div>' . $expected . '</div>');
149
        $this->assertEquals($input, $parsed->xpath('//div')[0]);
150
    }
151
 
11 efrain 152
    public function test_write_hint_basic(): void {
1 efrain 153
        $q = $this->make_test_question();
154
        $q->contextid = \context_system::instance()->id;
155
        $q->name = 'Short answer question';
156
        $q->questiontext = 'Name an amphibian: __________';
157
        $q->generalfeedback = 'Generalfeedback: frog or toad would have been OK.';
158
        if (!isset($q->options)) {
159
            $q->options = new \stdClass();
160
        }
161
        $q->options->usecase = false;
162
        $q->options->answers = array(
163
            13 => new question_answer(13, 'frog', 1.0, 'Frog is a very good answer.', FORMAT_HTML),
164
            14 => new question_answer(14, 'toad', 0.8, 'Toad is an OK good answer.', FORMAT_HTML),
165
            15 => new question_answer(15, '*', 0.0, 'That is a bad answer.', FORMAT_HTML),
166
        );
167
        $q->qtype = 'shortanswer';
168
        $q->hints = array(
169
            new question_hint(0, 'This is the first hint.', FORMAT_MOODLE),
170
        );
171
 
172
        $exporter = new qformat_xml();
173
        $xml = $exporter->writequestion($q);
174
 
175
        $this->assertMatchesRegularExpression('|<hint format=\"moodle_auto_format\">\s*<text>\s*' .
176
                'This is the first hint\.\s*</text>\s*</hint>|', $xml);
177
        $this->assertDoesNotMatchRegularExpression('|<shownumcorrect/>|', $xml);
178
        $this->assertDoesNotMatchRegularExpression('|<clearwrong/>|', $xml);
179
        $this->assertDoesNotMatchRegularExpression('|<options>|', $xml);
180
    }
181
 
11 efrain 182
    public function test_write_hint_with_parts(): void {
1 efrain 183
        $q = $this->make_test_question();
184
        $q->contextid = \context_system::instance()->id;
185
        $q->name = 'Matching question';
186
        $q->questiontext = 'Classify the animals.';
187
        $q->generalfeedback = 'Frogs and toads are amphibians, the others are mammals.';
188
        $q->qtype = 'match';
189
 
190
        if (!isset($q->options)) {
191
            $q->options = new \stdClass();
192
        }
193
        $q->options->shuffleanswers = 1;
194
        $q->options->correctfeedback = '';
195
        $q->options->correctfeedbackformat = FORMAT_HTML;
196
        $q->options->partiallycorrectfeedback = '';
197
        $q->options->partiallycorrectfeedbackformat = FORMAT_HTML;
198
        $q->options->incorrectfeedback = '';
199
        $q->options->incorrectfeedbackformat = FORMAT_HTML;
200
 
201
        $q->options->subquestions = array();
202
        $q->hints = array(
203
            new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, true),
204
            new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, false),
205
        );
206
 
207
        $exporter = new qformat_xml();
208
        $xml = $exporter->writequestion($q);
209
 
210
        $this->assertMatchesRegularExpression(
211
                '|<hint format=\"html\">\s*<text>\s*This is the first hint\.\s*</text>|', $xml);
212
        $this->assertMatchesRegularExpression(
213
                '|<hint format=\"html\">\s*<text>\s*This is the second hint\.\s*</text>|', $xml);
214
        list($ignored, $hint1, $hint2) = explode('<hint', $xml);
215
        $this->assertDoesNotMatchRegularExpression('|<shownumcorrect/>|', $hint1);
216
        $this->assertMatchesRegularExpression('|<clearwrong/>|', $hint1);
217
        $this->assertMatchesRegularExpression('|<shownumcorrect/>|', $hint2);
218
        $this->assertDoesNotMatchRegularExpression('|<clearwrong/>|', $hint2);
219
        $this->assertDoesNotMatchRegularExpression('|<options>|', $xml);
220
    }
221
 
11 efrain 222
    public function test_import_hints_no_parts(): void {
1 efrain 223
        $xml = <<<END
224
<question>
225
    <hint>
226
        <text>This is the first hint</text>
227
        <clearwrong/>
228
    </hint>
229
    <hint>
230
        <text>This is the second hint</text>
231
        <shownumcorrect/>
232
    </hint>
233
</question>
234
END;
235
 
236
        $questionxml = xmlize($xml);
237
        $qo = new \stdClass();
238
 
239
        $importer = new qformat_xml();
240
        $importer->import_hints($qo, $questionxml['question'], false, false, 'html');
241
 
242
        $this->assertEquals(array(
243
                array('text' => 'This is the first hint',
244
                        'format' => FORMAT_HTML),
245
                array('text' => 'This is the second hint',
246
                        'format' => FORMAT_HTML),
247
                ), $qo->hint);
248
        $this->assertFalse(isset($qo->hintclearwrong));
249
        $this->assertFalse(isset($qo->hintshownumcorrect));
250
    }
251
 
11 efrain 252
    public function test_import_hints_with_parts(): void {
1 efrain 253
        $xml = <<<END
254
<question>
255
    <hint>
256
        <text>This is the first hint</text>
257
        <clearwrong/>
258
    </hint>
259
    <hint>
260
        <text>This is the second hint</text>
261
        <shownumcorrect/>
262
    </hint>
263
</question>
264
END;
265
 
266
        $questionxml = xmlize($xml);
267
        $qo = new \stdClass();
268
 
269
        $importer = new qformat_xml();
270
        $importer->import_hints($qo, $questionxml['question'], true, true, 'html');
271
 
272
        $this->assertEquals(array(
273
                array('text' => 'This is the first hint',
274
                        'format' => FORMAT_HTML),
275
                array('text' => 'This is the second hint',
276
                        'format' => FORMAT_HTML),
277
                ), $qo->hint);
278
        $this->assertEquals(array(1, 0), $qo->hintclearwrong);
279
        $this->assertEquals(array(0, 1), $qo->hintshownumcorrect);
280
    }
281
 
11 efrain 282
    public function test_import_no_hints_no_error(): void {
1 efrain 283
        $xml = <<<END
284
<question>
285
</question>
286
END;
287
 
288
        $questionxml = xmlize($xml);
289
        $qo = new \stdClass();
290
 
291
        $importer = new qformat_xml();
292
        $importer->import_hints($qo, $questionxml['question'], 'html');
293
 
294
        $this->assertFalse(isset($qo->hint));
295
    }
296
 
11 efrain 297
    public function test_import_description(): void {
1 efrain 298
        $xml = '  <question type="description">
299
    <name>
300
      <text>A description</text>
301
    </name>
302
    <questiontext format="html">
303
      <text>The question text.</text>
304
    </questiontext>
305
    <generalfeedback>
306
      <text>Here is some general feedback.</text>
307
    </generalfeedback>
308
    <defaultgrade>0</defaultgrade>
309
    <penalty>0</penalty>
310
    <hidden>0</hidden>
311
    <tags>
312
      <tag><text>tagDescription</text></tag>
313
      <tag><text>tagTest</text></tag>
314
    </tags>
315
  </question>';
316
        $xmldata = xmlize($xml);
317
 
318
        $importer = new qformat_xml();
319
        $q = $importer->import_description($xmldata['question']);
320
 
321
        $expectedq = new \stdClass();
322
        $expectedq->qtype = 'description';
323
        $expectedq->name = 'A description';
324
        $expectedq->questiontext = 'The question text.';
325
        $expectedq->questiontextformat = FORMAT_HTML;
326
        $expectedq->generalfeedback = 'Here is some general feedback.';
327
        $expectedq->defaultmark = 0;
328
        $expectedq->length = 0;
329
        $expectedq->penalty = 0;
330
        $expectedq->tags = array('tagDescription', 'tagTest');
331
 
332
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
333
    }
334
 
11 efrain 335
    public function test_export_description(): void {
1 efrain 336
        $qdata = new \stdClass();
337
        $qdata->id = 123;
338
        $qdata->contextid = \context_system::instance()->id;
339
        $qdata->qtype = 'description';
340
        $qdata->name = 'A description';
341
        $qdata->questiontext = 'The question text.';
342
        $qdata->questiontextformat = FORMAT_HTML;
343
        $qdata->generalfeedback = 'Here is some general feedback.';
344
        $qdata->generalfeedbackformat = FORMAT_HTML;
345
        $qdata->defaultmark = 0;
346
        $qdata->length = 0;
347
        $qdata->penalty = 0;
348
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
349
        $qdata->idnumber = null;
350
 
351
        $exporter = new qformat_xml();
352
        $xml = $exporter->writequestion($qdata);
353
 
354
        $expectedxml = '<!-- question: 123  -->
355
  <question type="description">
356
    <name>
357
      <text>A description</text>
358
    </name>
359
    <questiontext format="html">
360
      <text>The question text.</text>
361
    </questiontext>
362
    <generalfeedback format="html">
363
      <text>Here is some general feedback.</text>
364
    </generalfeedback>
365
    <defaultgrade>0</defaultgrade>
366
    <penalty>0</penalty>
367
    <hidden>0</hidden>
368
    <idnumber></idnumber>
369
  </question>
370
';
371
 
372
        $this->assert_same_xml($expectedxml, $xml);
373
    }
374
 
11 efrain 375
    public function test_import_essay_20(): void {
1 efrain 376
        $xml = '  <question type="essay">
377
    <name>
378
      <text>An essay</text>
379
    </name>
380
    <questiontext format="moodle_auto_format">
381
      <text>Write something.</text>
382
    </questiontext>
383
    <generalfeedback>
384
      <text>I hope you wrote something interesting.</text>
385
    </generalfeedback>
386
    <defaultgrade>1</defaultgrade>
387
    <penalty>0</penalty>
388
    <hidden>0</hidden>
389
    <tags>
390
      <tag><text>tagEssay</text></tag>
391
      <tag><text>tagEssay20</text></tag>
392
      <tag><text>tagTest</text></tag>
393
    </tags>
394
  </question>';
395
        $xmldata = xmlize($xml);
396
 
397
        $importer = new qformat_xml();
398
        $q = $importer->import_essay($xmldata['question']);
399
 
400
        $expectedq = new \stdClass();
401
        $expectedq->qtype = 'essay';
402
        $expectedq->name = 'An essay';
403
        $expectedq->questiontext = 'Write something.';
404
        $expectedq->questiontextformat = FORMAT_MOODLE;
405
        $expectedq->generalfeedback = 'I hope you wrote something interesting.';
406
        $expectedq->defaultmark = 1;
407
        $expectedq->length = 1;
408
        $expectedq->penalty = 0;
409
        $expectedq->responseformat = 'editor';
410
        $expectedq->responserequired = 1;
411
        $expectedq->responsefieldlines = 15;
412
        $expectedq->minwordlimit = null;
413
        $expectedq->minwordenabled = false;
414
        $expectedq->maxwordlimit = null;
415
        $expectedq->maxwordenabled = false;
416
        $expectedq->attachments = 0;
417
        $expectedq->attachmentsrequired = 0;
418
        $expectedq->maxbytes = 0;
419
        $expectedq->filetypeslist = null;
420
        $expectedq->graderinfo['text'] = '';
421
        $expectedq->graderinfo['format'] = FORMAT_MOODLE;
422
        $expectedq->responsetemplate['text'] = '';
423
        $expectedq->responsetemplate['format'] = FORMAT_MOODLE;
424
        $expectedq->tags = array('tagEssay', 'tagEssay20', 'tagTest');
425
 
426
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
427
    }
428
 
11 efrain 429
    public function test_import_essay_21(): void {
1 efrain 430
        $xml = '  <question type="essay">
431
    <name>
432
      <text>An essay</text>
433
    </name>
434
    <questiontext format="moodle_auto_format">
435
      <text>Write something.</text>
436
    </questiontext>
437
    <generalfeedback>
438
      <text>I hope you wrote something interesting.</text>
439
    </generalfeedback>
440
    <defaultgrade>1</defaultgrade>
441
    <penalty>0</penalty>
442
    <hidden>0</hidden>
443
    <responseformat>monospaced</responseformat>
444
    <responserequired>0</responserequired>
445
    <responsefieldlines>42</responsefieldlines>
446
    <attachments>-1</attachments>
447
    <attachmentsrequired>1</attachmentsrequired>
448
    <graderinfo format="html">
449
        <text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
450
    </graderinfo>
451
    <responsetemplate format="html">
452
        <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
453
    </responsetemplate>
454
    <tags>
455
      <tag><text>tagEssay</text></tag>
456
      <tag><text>tagEssay21</text></tag>
457
      <tag><text>tagTest</text></tag>
458
    </tags>
459
  </question>';
460
        $xmldata = xmlize($xml);
461
 
462
        $importer = new qformat_xml();
463
        $q = $importer->import_essay($xmldata['question']);
464
 
465
        $expectedq = new \stdClass();
466
        $expectedq->qtype = 'essay';
467
        $expectedq->name = 'An essay';
468
        $expectedq->questiontext = 'Write something.';
469
        $expectedq->questiontextformat = FORMAT_MOODLE;
470
        $expectedq->generalfeedback = 'I hope you wrote something interesting.';
471
        $expectedq->defaultmark = 1;
472
        $expectedq->length = 1;
473
        $expectedq->penalty = 0;
474
        $expectedq->responseformat = 'monospaced';
475
        $expectedq->responserequired = 0;
476
        $expectedq->responsefieldlines = 42;
477
        $expectedq->minwordlimit = null;
478
        $expectedq->minwordenabled = false;
479
        $expectedq->maxwordlimit = null;
480
        $expectedq->maxwordenabled = false;
481
        $expectedq->attachments = -1;
482
        $expectedq->attachmentsrequired = 1;
483
        $expectedq->maxbytes = 0;
484
        $expectedq->filetypeslist = null;
485
        $expectedq->graderinfo['text'] = '<p>Grade <b>generously</b>!</p>';
486
        $expectedq->graderinfo['format'] = FORMAT_HTML;
487
        $expectedq->responsetemplate['text'] = '<p>Here is something <b>really</b> interesting.</p>';
488
        $expectedq->responsetemplate['format'] = FORMAT_HTML;
489
        $expectedq->tags = array('tagEssay', 'tagEssay21', 'tagTest');
490
 
491
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
492
    }
493
 
11 efrain 494
    public function test_import_essay_311(): void {
1 efrain 495
        $xml = '  <question type="essay">
496
    <name>
497
      <text>An essay</text>
498
    </name>
499
    <questiontext format="moodle_auto_format">
500
      <text>Write something.</text>
501
    </questiontext>
502
    <generalfeedback>
503
      <text>I hope you wrote something interesting.</text>
504
    </generalfeedback>
505
    <defaultgrade>1</defaultgrade>
506
    <penalty>0</penalty>
507
    <hidden>0</hidden>
508
    <responseformat>monospaced</responseformat>
509
    <responserequired>0</responserequired>
510
    <responsefieldlines>42</responsefieldlines>
511
    <minwordlimit>10</minwordlimit>
512
    <maxwordlimit>20</maxwordlimit>
513
    <attachments>-1</attachments>
514
    <attachmentsrequired>1</attachmentsrequired>
515
    <maxbytes>52428800</maxbytes>
516
    <filetypeslist>.pdf,.zip.,.docx</filetypeslist>
517
    <graderinfo format="html">
518
        <text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
519
    </graderinfo>
520
    <responsetemplate format="html">
521
        <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
522
    </responsetemplate>
523
    <tags>
524
      <tag><text>tagEssay</text></tag>
525
      <tag><text>tagEssay21</text></tag>
526
      <tag><text>tagTest</text></tag>
527
    </tags>
528
  </question>';
529
        $xmldata = xmlize($xml);
530
 
531
        $importer = new qformat_xml();
532
        $q = $importer->import_essay($xmldata['question']);
533
 
534
        $expectedq = new \stdClass();
535
        $expectedq->qtype = 'essay';
536
        $expectedq->name = 'An essay';
537
        $expectedq->questiontext = 'Write something.';
538
        $expectedq->questiontextformat = FORMAT_MOODLE;
539
        $expectedq->generalfeedback = 'I hope you wrote something interesting.';
540
        $expectedq->defaultmark = 1;
541
        $expectedq->length = 1;
542
        $expectedq->penalty = 0;
543
        $expectedq->responseformat = 'monospaced';
544
        $expectedq->responserequired = 0;
545
        $expectedq->responsefieldlines = 42;
546
        $expectedq->minwordlimit = 10;
547
        $expectedq->minwordenabled = true;
548
        $expectedq->maxwordlimit = 20;
549
        $expectedq->maxwordenabled = true;
550
        $expectedq->attachments = -1;
551
        $expectedq->attachmentsrequired = 1;
552
        $expectedq->maxbytes = 52428800; // 50MB.
553
        $expectedq->filetypeslist = '.pdf,.zip.,.docx';
554
        $expectedq->graderinfo['text'] = '<p>Grade <b>generously</b>!</p>';
555
        $expectedq->graderinfo['format'] = FORMAT_HTML;
556
        $expectedq->responsetemplate['text'] = '<p>Here is something <b>really</b> interesting.</p>';
557
        $expectedq->responsetemplate['format'] = FORMAT_HTML;
558
        $expectedq->tags = array('tagEssay', 'tagEssay21', 'tagTest');
559
 
560
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
561
    }
562
 
11 efrain 563
    public function test_export_essay(): void {
1 efrain 564
        $qdata = new \stdClass();
565
        $qdata->id = 123;
566
        $qdata->contextid = \context_system::instance()->id;
567
        $qdata->qtype = 'essay';
568
        $qdata->name = 'An essay';
569
        $qdata->questiontext = 'Write something.';
570
        $qdata->questiontextformat = FORMAT_MOODLE;
571
        $qdata->generalfeedback = 'I hope you wrote something interesting.';
572
        $qdata->generalfeedbackformat = FORMAT_MOODLE;
573
        $qdata->defaultmark = 1;
574
        $qdata->length = 1;
575
        $qdata->penalty = 0;
576
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
577
        $qdata->idnumber = null;
578
        $qdata->options = new \stdClass();
579
        $qdata->options->id = 456;
580
        $qdata->options->questionid = 123;
581
        $qdata->options->responseformat = 'monospaced';
582
        $qdata->options->responserequired = 0;
583
        $qdata->options->responsefieldlines = 42;
584
        $qdata->options->minwordlimit = 10;
585
        $qdata->options->maxwordlimit = 20;
586
        $qdata->options->attachments = -1;
587
        $qdata->options->attachmentsrequired = 1;
588
        $qdata->options->graderinfo = '<p>Grade <b>generously</b>!</p>';
589
        $qdata->options->graderinfoformat = FORMAT_HTML;
590
        $qdata->options->responsetemplate = '<p>Here is something <b>really</b> interesting.</p>';
591
        $qdata->options->responsetemplateformat = FORMAT_HTML;
592
        $qdata->options->maxbytes = 52428800; // 50MB.
593
        $qdata->options->filetypeslist = '.pdf,.zip.,.docx';
594
        $exporter = new qformat_xml();
595
        $xml = $exporter->writequestion($qdata);
596
 
597
        $expectedxml = '<!-- question: 123  -->
598
  <question type="essay">
599
    <name>
600
      <text>An essay</text>
601
    </name>
602
    <questiontext format="moodle_auto_format">
603
      <text>Write something.</text>
604
    </questiontext>
605
    <generalfeedback format="moodle_auto_format">
606
      <text>I hope you wrote something interesting.</text>
607
    </generalfeedback>
608
    <defaultgrade>1</defaultgrade>
609
    <penalty>0</penalty>
610
    <hidden>0</hidden>
611
    <idnumber></idnumber>
612
    <responseformat>monospaced</responseformat>
613
    <responserequired>0</responserequired>
614
    <responsefieldlines>42</responsefieldlines>
615
    <minwordlimit>10</minwordlimit>
616
    <maxwordlimit>20</maxwordlimit>
617
    <attachments>-1</attachments>
618
    <attachmentsrequired>1</attachmentsrequired>
619
    <maxbytes>52428800</maxbytes>
620
    <filetypeslist>.pdf,.zip.,.docx</filetypeslist>
621
    <graderinfo format="html">
622
      <text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
623
    </graderinfo>
624
    <responsetemplate format="html">
625
      <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
626
    </responsetemplate>
627
  </question>
628
';
629
 
630
        $this->assert_same_xml($expectedxml, $xml);
631
    }
632
 
11 efrain 633
    public function test_import_match_19(): void {
1 efrain 634
        $xml = '  <question type="matching">
635
    <name>
636
      <text>Matching question</text>
637
    </name>
638
    <questiontext format="html">
639
      <text>Match the upper and lower case letters.</text>
640
    </questiontext>
641
    <generalfeedback>
642
      <text>The answer is A -> a, B -> b and C -> c.</text>
643
    </generalfeedback>
644
    <defaultgrade>1</defaultgrade>
645
    <penalty>0.3333333</penalty>
646
    <hidden>0</hidden>
647
    <shuffleanswers>false</shuffleanswers>
648
    <correctfeedback>
649
      <text>Well done.</text>
650
    </correctfeedback>
651
    <partiallycorrectfeedback>
652
      <text>Not entirely.</text>
653
    </partiallycorrectfeedback>
654
    <incorrectfeedback>
655
      <text>Completely wrong!</text>
656
    </incorrectfeedback>
657
    <subquestion>
658
      <text>A</text>
659
      <answer>
660
        <text>a</text>
661
      </answer>
662
    </subquestion>
663
    <subquestion>
664
      <text>B</text>
665
      <answer>
666
        <text>b</text>
667
      </answer>
668
    </subquestion>
669
    <subquestion>
670
      <text>C</text>
671
      <answer>
672
        <text>c</text>
673
      </answer>
674
    </subquestion>
675
    <subquestion>
676
      <text></text>
677
      <answer>
678
        <text>d</text>
679
      </answer>
680
    </subquestion>
681
    <hint>
682
      <text>Hint 1</text>
683
      <shownumcorrect />
684
    </hint>
685
    <hint>
686
      <text></text>
687
      <shownumcorrect />
688
      <clearwrong />
689
    </hint>
690
    <tags>
691
      <tag><text>tagMatching</text></tag>
692
      <tag><text>tagTest</text></tag>
693
    </tags>
694
  </question>';
695
        $xmldata = xmlize($xml);
696
 
697
        $importer = new qformat_xml();
698
        $q = $importer->import_match($xmldata['question']);
699
 
700
        $expectedq = new \stdClass();
701
        $expectedq->qtype = 'match';
702
        $expectedq->name = 'Matching question';
703
        $expectedq->questiontext = 'Match the upper and lower case letters.';
704
        $expectedq->questiontextformat = FORMAT_HTML;
705
        $expectedq->correctfeedback = array('text' => 'Well done.',
706
                'format' => FORMAT_HTML);
707
        $expectedq->partiallycorrectfeedback = array('text' => 'Not entirely.',
708
                'format' => FORMAT_HTML);
709
        $expectedq->shownumcorrect = false;
710
        $expectedq->incorrectfeedback = array('text' => 'Completely wrong!',
711
                'format' => FORMAT_HTML);
712
        $expectedq->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
713
        $expectedq->generalfeedbackformat = FORMAT_HTML;
714
        $expectedq->defaultmark = 1;
715
        $expectedq->length = 1;
716
        $expectedq->penalty = 0.3333333;
717
        $expectedq->shuffleanswers = 0;
718
        $expectedq->subquestions = array(
719
            array('text' => 'A', 'format' => FORMAT_HTML),
720
            array('text' => 'B', 'format' => FORMAT_HTML),
721
            array('text' => 'C', 'format' => FORMAT_HTML),
722
            array('text' => '', 'format' => FORMAT_HTML));
723
        $expectedq->subanswers = array('a', 'b', 'c', 'd');
724
        $expectedq->hint = array(
725
            array('text' => 'Hint 1', 'format' => FORMAT_HTML),
726
            array('text' => '', 'format' => FORMAT_HTML),
727
        );
728
        $expectedq->hintshownumcorrect = array(true, true);
729
        $expectedq->hintclearwrong = array(false, true);
730
        $expectedq->tags = array('tagMatching', 'tagTest');
731
 
732
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
733
    }
734
 
11 efrain 735
    public function test_export_match(): void {
1 efrain 736
        $qdata = new \stdClass();
737
        $qdata->id = 123;
738
        $qdata->contextid = \context_system::instance()->id;
739
        $qdata->qtype = 'match';
740
        $qdata->name = 'Matching question';
741
        $qdata->questiontext = 'Match the upper and lower case letters.';
742
        $qdata->questiontextformat = FORMAT_HTML;
743
        $qdata->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
744
        $qdata->generalfeedbackformat = FORMAT_HTML;
745
        $qdata->defaultmark = 1;
746
        $qdata->length = 1;
747
        $qdata->penalty = 0.3333333;
748
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
749
        $qdata->idnumber = null;
750
 
751
        $qdata->options = new \stdClass();
752
        $qdata->options->shuffleanswers = 1;
753
        $qdata->options->correctfeedback = 'Well done.';
754
        $qdata->options->correctfeedbackformat = FORMAT_HTML;
755
        $qdata->options->partiallycorrectfeedback = 'Not entirely.';
756
        $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML;
757
        $qdata->options->shownumcorrect = false;
758
        $qdata->options->incorrectfeedback = 'Completely wrong!';
759
        $qdata->options->incorrectfeedbackformat = FORMAT_HTML;
760
 
761
        $subq1 = new \stdClass();
762
        $subq1->id = -4;
763
        $subq1->questiontext = 'A';
764
        $subq1->questiontextformat = FORMAT_HTML;
765
        $subq1->answertext = 'a';
766
 
767
        $subq2 = new \stdClass();
768
        $subq2->id = -3;
769
        $subq2->questiontext = 'B';
770
        $subq2->questiontextformat = FORMAT_HTML;
771
        $subq2->answertext = 'b';
772
 
773
        $subq3 = new \stdClass();
774
        $subq3->id = -2;
775
        $subq3->questiontext = 'C';
776
        $subq3->questiontextformat = FORMAT_HTML;
777
        $subq3->answertext = 'c';
778
 
779
        $subq4 = new \stdClass();
780
        $subq4->id = -1;
781
        $subq4->questiontext = '';
782
        $subq4->questiontextformat = FORMAT_HTML;
783
        $subq4->answertext = 'd';
784
 
785
        $qdata->options->subquestions = array(
786
                $subq1, $subq2, $subq3, $subq4);
787
 
788
        $qdata->hints = array(
789
            new question_hint_with_parts(0, 'Hint 1', FORMAT_HTML, true, false),
790
            new question_hint_with_parts(0, '', FORMAT_HTML, true, true),
791
        );
792
 
793
        $exporter = new qformat_xml();
794
        $xml = $exporter->writequestion($qdata);
795
 
796
        $expectedxml = '<!-- question: 123  -->
797
  <question type="matching">
798
    <name>
799
      <text>Matching question</text>
800
    </name>
801
    <questiontext format="html">
802
      <text>Match the upper and lower case letters.</text>
803
    </questiontext>
804
    <generalfeedback format="html">
805
      <text><![CDATA[The answer is A -> a, B -> b and C -> c.]]></text>
806
    </generalfeedback>
807
    <defaultgrade>1</defaultgrade>
808
    <penalty>0.3333333</penalty>
809
    <hidden>0</hidden>
810
    <idnumber></idnumber>
811
    <shuffleanswers>true</shuffleanswers>
812
    <correctfeedback format="html">
813
      <text>Well done.</text>
814
    </correctfeedback>
815
    <partiallycorrectfeedback format="html">
816
      <text>Not entirely.</text>
817
    </partiallycorrectfeedback>
818
    <incorrectfeedback format="html">
819
      <text>Completely wrong!</text>
820
    </incorrectfeedback>
821
    <subquestion format="html">
822
      <text>A</text>
823
      <answer>
824
        <text>a</text>
825
      </answer>
826
    </subquestion>
827
    <subquestion format="html">
828
      <text>B</text>
829
      <answer>
830
        <text>b</text>
831
      </answer>
832
    </subquestion>
833
    <subquestion format="html">
834
      <text>C</text>
835
      <answer>
836
        <text>c</text>
837
      </answer>
838
    </subquestion>
839
    <subquestion format="html">
840
      <text></text>
841
      <answer>
842
        <text>d</text>
843
      </answer>
844
    </subquestion>
845
    <hint format="html">
846
      <text>Hint 1</text>
847
      <shownumcorrect/>
848
    </hint>
849
    <hint format="html">
850
      <text></text>
851
      <shownumcorrect/>
852
      <clearwrong/>
853
    </hint>
854
  </question>
855
';
856
 
857
        $this->assert_same_xml($expectedxml, $xml);
858
    }
859
 
11 efrain 860
    public function test_import_multichoice_19(): void {
1 efrain 861
        $xml = '  <question type="multichoice">
862
    <name>
863
      <text>Multiple choice question</text>
864
    </name>
865
    <questiontext format="html">
866
      <text>Which are the even numbers?</text>
867
    </questiontext>
868
    <generalfeedback>
869
      <text>The even numbers are 2 and 4.</text>
870
    </generalfeedback>
871
    <defaultgrade>2</defaultgrade>
872
    <penalty>0.3333333</penalty>
873
    <hidden>0</hidden>
874
    <single>false</single>
875
    <shuffleanswers>false</shuffleanswers>
876
    <answernumbering>abc</answernumbering>
877
    <correctfeedback>
878
      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
879
    </correctfeedback>
880
    <partiallycorrectfeedback>
881
      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
882
    </partiallycorrectfeedback>
883
    <incorrectfeedback>
884
      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
885
    </incorrectfeedback>
886
    <shownumcorrect/>
887
    <answer fraction="0">
888
      <text>1</text>
889
      <feedback>
890
        <text></text>
891
      </feedback>
892
    </answer>
893
    <answer fraction="100">
894
      <text>2</text>
895
      <feedback>
896
        <text></text>
897
      </feedback>
898
    </answer>
899
    <answer fraction="0">
900
      <text>3</text>
901
      <feedback>
902
        <text></text>
903
      </feedback>
904
    </answer>
905
    <answer fraction="100">
906
      <text>4</text>
907
      <feedback>
908
        <text></text>
909
      </feedback>
910
    </answer>
911
    <hint>
912
      <text>Hint 1.</text>
913
    </hint>
914
    <hint>
915
      <text>Hint 2.</text>
916
    </hint>
917
  </question>';
918
        $xmldata = xmlize($xml);
919
 
920
        $importer = new qformat_xml();
921
        $q = $importer->import_multichoice($xmldata['question']);
922
 
923
        $expectedq = new \stdClass();
924
        $expectedq->qtype = 'multichoice';
925
        $expectedq->name = 'Multiple choice question';
926
        $expectedq->questiontext = 'Which are the even numbers?';
927
        $expectedq->questiontextformat = FORMAT_HTML;
928
        $expectedq->correctfeedback = array(
929
                'text'   => '<p>Your answer is correct.</p>',
930
                'format' => FORMAT_HTML);
931
        $expectedq->shownumcorrect = false;
932
        $expectedq->partiallycorrectfeedback = array(
933
                'text'   => '<p>Your answer is partially correct.</p>',
934
                'format' => FORMAT_HTML);
935
        $expectedq->shownumcorrect = true;
936
        $expectedq->incorrectfeedback = array(
937
                'text'   => '<p>Your answer is incorrect.</p>',
938
                'format' => FORMAT_HTML);
939
        $expectedq->generalfeedback = 'The even numbers are 2 and 4.';
940
        $expectedq->defaultmark = 2;
941
        $expectedq->length = 1;
942
        $expectedq->penalty = 0.3333333;
943
        $expectedq->shuffleanswers = 0;
944
        $expectedq->single = false;
945
 
946
        $expectedq->answer = array(
947
            array('text' => '1', 'format' => FORMAT_HTML),
948
            array('text' => '2', 'format' => FORMAT_HTML),
949
            array('text' => '3', 'format' => FORMAT_HTML),
950
            array('text' => '4', 'format' => FORMAT_HTML));
951
        $expectedq->fraction = array(0, 1, 0, 1);
952
        $expectedq->feedback = array(
953
            array('text' => '', 'format' => FORMAT_HTML),
954
            array('text' => '', 'format' => FORMAT_HTML),
955
            array('text' => '', 'format' => FORMAT_HTML),
956
            array('text' => '', 'format' => FORMAT_HTML));
957
 
958
        $expectedq->hint = array(
959
            array('text' => 'Hint 1.', 'format' => FORMAT_HTML),
960
            array('text' => 'Hint 2.', 'format' => FORMAT_HTML),
961
        );
962
        $expectedq->hintshownumcorrect = array(false, false);
963
        $expectedq->hintclearwrong = array(false, false);
964
 
965
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
966
    }
967
 
11 efrain 968
    public function test_export_multichoice(): void {
1 efrain 969
        $qdata = new \stdClass();
970
        $qdata->id = 123;
971
        $qdata->contextid = \context_system::instance()->id;
972
        $qdata->qtype = 'multichoice';
973
        $qdata->name = 'Multiple choice question';
974
        $qdata->questiontext = 'Which are the even numbers?';
975
        $qdata->questiontextformat = FORMAT_HTML;
976
        $qdata->generalfeedback = 'The even numbers are 2 and 4.';
977
        $qdata->generalfeedbackformat = FORMAT_HTML;
978
        $qdata->defaultmark = 2;
979
        $qdata->length = 1;
980
        $qdata->penalty = 0.3333333;
981
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
982
        $qdata->idnumber = null;
983
 
984
        $qdata->options = new \stdClass();
985
        $qdata->options->single = 0;
986
        $qdata->options->shuffleanswers = 0;
987
        $qdata->options->answernumbering = 'abc';
988
        $qdata->options->showstandardinstruction = 0;
989
        $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
990
        $qdata->options->correctfeedbackformat = FORMAT_HTML;
991
        $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
992
        $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML;
993
        $qdata->options->shownumcorrect = 1;
994
        $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
995
        $qdata->options->incorrectfeedbackformat = FORMAT_HTML;
996
 
997
        $qdata->options->answers = array(
998
            13 => new question_answer(13, '1', 0, '', FORMAT_HTML),
999
            14 => new question_answer(14, '2', 1, '', FORMAT_HTML),
1000
            15 => new question_answer(15, '3', 0, '', FORMAT_HTML),
1001
            16 => new question_answer(16, '4', 1, '', FORMAT_HTML),
1002
        );
1003
 
1004
        $qdata->hints = array(
1005
            new question_hint_with_parts(0, 'Hint 1.', FORMAT_HTML, false, false),
1006
            new question_hint_with_parts(0, 'Hint 2.', FORMAT_HTML, false, false),
1007
        );
1008
 
1009
        $exporter = new qformat_xml();
1010
        $xml = $exporter->writequestion($qdata);
1011
 
1012
        $expectedxml = '<!-- question: 123  -->
1013
  <question type="multichoice">
1014
    <name>
1015
      <text>Multiple choice question</text>
1016
    </name>
1017
    <questiontext format="html">
1018
      <text>Which are the even numbers?</text>
1019
    </questiontext>
1020
    <generalfeedback format="html">
1021
      <text>The even numbers are 2 and 4.</text>
1022
    </generalfeedback>
1023
    <defaultgrade>2</defaultgrade>
1024
    <penalty>0.3333333</penalty>
1025
    <hidden>0</hidden>
1026
    <idnumber></idnumber>
1027
    <single>false</single>
1028
    <shuffleanswers>false</shuffleanswers>
1029
    <answernumbering>abc</answernumbering>
1030
    <showstandardinstruction>0</showstandardinstruction>
1031
    <correctfeedback format="html">
1032
      <text><![CDATA[<p>Your answer is correct.</p>]]></text>
1033
    </correctfeedback>
1034
    <partiallycorrectfeedback format="html">
1035
      <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
1036
    </partiallycorrectfeedback>
1037
    <incorrectfeedback format="html">
1038
      <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
1039
    </incorrectfeedback>
1040
    <shownumcorrect/>
1041
    <answer fraction="0" format="plain_text">
1042
      <text>1</text>
1043
      <feedback format="html">
1044
        <text></text>
1045
      </feedback>
1046
    </answer>
1047
    <answer fraction="100" format="plain_text">
1048
      <text>2</text>
1049
      <feedback format="html">
1050
        <text></text>
1051
      </feedback>
1052
    </answer>
1053
    <answer fraction="0" format="plain_text">
1054
      <text>3</text>
1055
      <feedback format="html">
1056
        <text></text>
1057
      </feedback>
1058
    </answer>
1059
    <answer fraction="100" format="plain_text">
1060
      <text>4</text>
1061
      <feedback format="html">
1062
        <text></text>
1063
      </feedback>
1064
    </answer>
1065
    <hint format="html">
1066
      <text>Hint 1.</text>
1067
    </hint>
1068
    <hint format="html">
1069
      <text>Hint 2.</text>
1070
    </hint>
1071
  </question>
1072
';
1073
 
1074
        $this->assert_same_xml($expectedxml, $xml);
1075
    }
1076
 
11 efrain 1077
    public function test_import_numerical_19(): void {
1 efrain 1078
        $xml = '  <question type="numerical">
1079
    <name>
1080
      <text>Numerical question</text>
1081
    </name>
1082
    <questiontext format="html">
1083
      <text>What is the answer?</text>
1084
    </questiontext>
1085
    <generalfeedback>
1086
      <text>General feedback: Think Hitch-hikers guide to the Galaxy.</text>
1087
    </generalfeedback>
1088
    <defaultgrade>1</defaultgrade>
1089
    <penalty>0.1</penalty>
1090
    <hidden>0</hidden>
1091
    <answer fraction="100">
1092
      <text>42</text>
1093
      <feedback>
1094
        <text>Well done!</text>
1095
      </feedback>
1096
      <tolerance>0.001</tolerance>
1097
    </answer>
1098
    <answer fraction="0">
1099
      <text>13</text>
1100
      <feedback>
1101
        <text>What were you thinking?!</text>
1102
      </feedback>
1103
      <tolerance>1</tolerance>
1104
    </answer>
1105
    <answer fraction="0">
1106
      <text>*</text>
1107
      <feedback>
1108
        <text>Completely wrong.</text>
1109
      </feedback>
1110
      <tolerance></tolerance>
1111
    </answer>
1112
  </question>';
1113
        $xmldata = xmlize($xml);
1114
 
1115
        $importer = new qformat_xml();
1116
        $q = $importer->import_numerical($xmldata['question']);
1117
 
1118
        $expectedq = new \stdClass();
1119
        $expectedq->qtype = 'numerical';
1120
        $expectedq->name = 'Numerical question';
1121
        $expectedq->questiontext = 'What is the answer?';
1122
        $expectedq->questiontextformat = FORMAT_HTML;
1123
        $expectedq->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
1124
        $expectedq->generalfeedbackformat = FORMAT_HTML;
1125
        $expectedq->defaultmark = 1;
1126
        $expectedq->length = 1;
1127
        $expectedq->penalty = 0.1;
1128
 
1129
        $expectedq->answer = array('42', '13', '*');
1130
        $expectedq->fraction = array(1, 0, 0);
1131
        $expectedq->feedback = array(
1132
            array('text' => 'Well done!',
1133
                    'format' => FORMAT_HTML),
1134
            array('text' => 'What were you thinking?!',
1135
                    'format' => FORMAT_HTML),
1136
            array('text' => 'Completely wrong.',
1137
                    'format' => FORMAT_HTML));
1138
        $expectedq->tolerance = array(0.001, 1, '');
1139
 
1140
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1141
    }
1142
 
11 efrain 1143
    public function test_export_numerical(): void {
1 efrain 1144
        question_bank::load_question_definition_classes('numerical');
1145
 
1146
        $qdata = new \stdClass();
1147
        $qdata->id = 123;
1148
        $qdata->contextid = \context_system::instance()->id;
1149
        $qdata->qtype = 'numerical';
1150
        $qdata->name = 'Numerical question';
1151
        $qdata->questiontext = 'What is the answer?';
1152
        $qdata->questiontextformat = FORMAT_HTML;
1153
        $qdata->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
1154
        $qdata->generalfeedbackformat = FORMAT_HTML;
1155
        $qdata->defaultmark = 1;
1156
        $qdata->length = 1;
1157
        $qdata->penalty = 0.1;
1158
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
1159
        $qdata->idnumber = null;
1160
 
1161
        $qdata->options = new \stdClass();
1162
        $qdata->options->answers = array(
1163
            13 => new qtype_numerical_answer(13, '42', 1, 'Well done!',
1164
                    FORMAT_HTML, 0.001),
1165
            14 => new qtype_numerical_answer(14, '13', 0, 'What were you thinking?!',
1166
                    FORMAT_HTML, 1),
1167
            15 => new qtype_numerical_answer(15, '*', 0, 'Completely wrong.',
1168
                    FORMAT_HTML, ''),
1169
        );
1170
 
1171
        $qdata->options->units = array();
1172
 
1173
        $exporter = new qformat_xml();
1174
        $xml = $exporter->writequestion($qdata);
1175
 
1176
        $expectedxml = '<!-- question: 123  -->
1177
  <question type="numerical">
1178
    <name>
1179
      <text>Numerical question</text>
1180
    </name>
1181
    <questiontext format="html">
1182
      <text>What is the answer?</text>
1183
    </questiontext>
1184
    <generalfeedback format="html">
1185
      <text>General feedback: Think Hitch-hikers guide to the Galaxy.</text>
1186
    </generalfeedback>
1187
    <defaultgrade>1</defaultgrade>
1188
    <penalty>0.1</penalty>
1189
    <hidden>0</hidden>
1190
    <idnumber></idnumber>
1191
    <answer fraction="100" format="plain_text">
1192
      <text>42</text>
1193
      <feedback format="html">
1194
        <text>Well done!</text>
1195
      </feedback>
1196
      <tolerance>0.001</tolerance>
1197
    </answer>
1198
    <answer fraction="0" format="plain_text">
1199
      <text>13</text>
1200
      <feedback format="html">
1201
        <text>What were you thinking?!</text>
1202
      </feedback>
1203
      <tolerance>1</tolerance>
1204
    </answer>
1205
    <answer fraction="0" format="plain_text">
1206
      <text>*</text>
1207
      <feedback format="html">
1208
        <text>Completely wrong.</text>
1209
      </feedback>
1210
      <tolerance>0</tolerance>
1211
    </answer>
1212
  </question>
1213
';
1214
 
1215
        $this->assert_same_xml($expectedxml, $xml);
1216
    }
1217
 
11 efrain 1218
    public function test_import_shortanswer_19(): void {
1 efrain 1219
        $xml = '  <question type="shortanswer">
1220
    <name>
1221
      <text>Short answer question</text>
1222
    </name>
1223
    <questiontext format="html">
1224
      <text>Fill in the gap in this sequence: Alpha, ________, Gamma.</text>
1225
    </questiontext>
1226
    <generalfeedback>
1227
      <text>The answer is Beta.</text>
1228
    </generalfeedback>
1229
    <defaultgrade>1</defaultgrade>
1230
    <penalty>0.3333333</penalty>
1231
    <hidden>0</hidden>
1232
    <usecase>0</usecase>
1233
    <answer fraction="100" format="plain_text">
1234
      <text>Beta</text>
1235
      <feedback>
1236
        <text>Well done!</text>
1237
      </feedback>
1238
    </answer>
1239
    <answer fraction="0" format="plain_text">
1240
      <text>*</text>
1241
      <feedback>
1242
        <text>Doh!</text>
1243
      </feedback>
1244
    </answer>
1245
    <hint>
1246
      <text>Hint 1</text>
1247
    </hint>
1248
    <hint>
1249
      <text>Hint 2</text>
1250
    </hint>
1251
  </question>';
1252
        $xmldata = xmlize($xml);
1253
 
1254
        $importer = new qformat_xml();
1255
        $q = $importer->import_shortanswer($xmldata['question']);
1256
 
1257
        $expectedq = new \stdClass();
1258
        $expectedq->qtype = 'shortanswer';
1259
        $expectedq->name = 'Short answer question';
1260
        $expectedq->questiontext = 'Fill in the gap in this sequence: Alpha, ________, Gamma.';
1261
        $expectedq->questiontextformat = FORMAT_HTML;
1262
        $expectedq->generalfeedback = 'The answer is Beta.';
1263
        $expectedq->usecase = false;
1264
        $expectedq->defaultmark = 1;
1265
        $expectedq->length = 1;
1266
        $expectedq->penalty = 0.3333333;
1267
 
1268
        $expectedq->answer = array('Beta', '*');
1269
        $expectedq->fraction = array(1, 0);
1270
        $expectedq->feedback = array(
1271
            array('text' => 'Well done!', 'format' => FORMAT_HTML),
1272
            array('text' => 'Doh!', 'format' => FORMAT_HTML));
1273
 
1274
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1275
    }
1276
 
11 efrain 1277
    public function test_export_shortanswer(): void {
1 efrain 1278
        $qdata = new \stdClass();
1279
        $qdata->id = 123;
1280
        $qdata->contextid = \context_system::instance()->id;
1281
        $qdata->qtype = 'shortanswer';
1282
        $qdata->name = 'Short answer question';
1283
        $qdata->questiontext = 'Fill in the gap in this sequence: Alpha, ________, Gamma.';
1284
        $qdata->questiontextformat = FORMAT_HTML;
1285
        $qdata->generalfeedback = 'The answer is Beta.';
1286
        $qdata->generalfeedbackformat = FORMAT_HTML;
1287
        $qdata->defaultmark = 1;
1288
        $qdata->length = 1;
1289
        $qdata->penalty = 0.3333333;
1290
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
1291
        $qdata->idnumber = null;
1292
 
1293
        $qdata->options = new \stdClass();
1294
        $qdata->options->usecase = 0;
1295
 
1296
        $qdata->options->answers = array(
1297
            13 => new question_answer(13, 'Beta', 1, 'Well done!', FORMAT_HTML),
1298
            14 => new question_answer(14, '*', 0, 'Doh!', FORMAT_HTML),
1299
        );
1300
 
1301
        $qdata->hints = array(
1302
            new question_hint(0, 'Hint 1', FORMAT_HTML),
1303
            new question_hint(0, 'Hint 2', FORMAT_HTML),
1304
        );
1305
 
1306
        $exporter = new qformat_xml();
1307
        $xml = $exporter->writequestion($qdata);
1308
 
1309
        $expectedxml = '<!-- question: 123  -->
1310
  <question type="shortanswer">
1311
    <name>
1312
      <text>Short answer question</text>
1313
    </name>
1314
    <questiontext format="html">
1315
      <text>Fill in the gap in this sequence: Alpha, ________, Gamma.</text>
1316
    </questiontext>
1317
    <generalfeedback format="html">
1318
      <text>The answer is Beta.</text>
1319
    </generalfeedback>
1320
    <defaultgrade>1</defaultgrade>
1321
    <penalty>0.3333333</penalty>
1322
    <hidden>0</hidden>
1323
    <idnumber></idnumber>
1324
    <usecase>0</usecase>
1325
    <answer fraction="100" format="plain_text">
1326
      <text>Beta</text>
1327
      <feedback format="html">
1328
        <text>Well done!</text>
1329
      </feedback>
1330
    </answer>
1331
    <answer fraction="0" format="plain_text">
1332
      <text>*</text>
1333
      <feedback format="html">
1334
        <text>Doh!</text>
1335
      </feedback>
1336
    </answer>
1337
    <hint format="html">
1338
      <text>Hint 1</text>
1339
    </hint>
1340
    <hint format="html">
1341
      <text>Hint 2</text>
1342
    </hint>
1343
  </question>
1344
';
1345
 
1346
        $this->assert_same_xml($expectedxml, $xml);
1347
    }
1348
 
11 efrain 1349
    public function test_import_truefalse_19(): void {
1 efrain 1350
        $xml = '  <question type="truefalse">
1351
    <name>
1352
      <text>True false question</text>
1353
    </name>
1354
    <questiontext format="html">
1355
      <text>The answer is true.</text>
1356
    </questiontext>
1357
    <generalfeedback>
1358
      <text>General feedback: You should have chosen true.</text>
1359
    </generalfeedback>
1360
    <defaultgrade>1</defaultgrade>
1361
    <penalty>1</penalty>
1362
    <hidden>0</hidden>
1363
    <answer fraction="100">
1364
      <text>true</text>
1365
      <feedback>
1366
        <text>Well done!</text>
1367
      </feedback>
1368
    </answer>
1369
    <answer fraction="0">
1370
      <text>false</text>
1371
      <feedback>
1372
        <text>Doh!</text>
1373
      </feedback>
1374
    </answer>
1375
  </question>';
1376
        $xmldata = xmlize($xml);
1377
 
1378
        $importer = new qformat_xml();
1379
        $q = $importer->import_truefalse($xmldata['question']);
1380
 
1381
        $expectedq = new \stdClass();
1382
        $expectedq->qtype = 'truefalse';
1383
        $expectedq->name = 'True false question';
1384
        $expectedq->questiontext = 'The answer is true.';
1385
        $expectedq->questiontextformat = FORMAT_HTML;
1386
        $expectedq->generalfeedback = 'General feedback: You should have chosen true.';
1387
        $expectedq->defaultmark = 1;
1388
        $expectedq->length = 1;
1389
        $expectedq->penalty = 1;
1390
 
1391
        $expectedq->feedbacktrue = array('text' => 'Well done!',
1392
                'format' => FORMAT_HTML);
1393
        $expectedq->feedbackfalse = array('text' => 'Doh!',
1394
                'format' => FORMAT_HTML);
1395
        $expectedq->correctanswer = true;
1396
 
1397
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1398
    }
1399
 
11 efrain 1400
    public function test_import_truefalse_with_idnumber(): void {
1 efrain 1401
        $xml = '  <question type="truefalse">
1402
    <name>
1403
      <text>True false question</text>
1404
    </name>
1405
    <questiontext format="html">
1406
      <text>The answer is true.</text>
1407
    </questiontext>
1408
    <generalfeedback>
1409
      <text>General feedback: You should have chosen true.</text>
1410
    </generalfeedback>
1411
    <defaultgrade>1</defaultgrade>
1412
    <penalty>1</penalty>
1413
    <hidden>0</hidden>
1414
    <idnumber>TestIdNum1</idnumber>
1415
    <answer fraction="100">
1416
      <text>true</text>
1417
      <feedback>
1418
        <text>Well done!</text>
1419
      </feedback>
1420
    </answer>
1421
    <answer fraction="0">
1422
      <text>false</text>
1423
      <feedback>
1424
        <text>Doh!</text>
1425
      </feedback>
1426
    </answer>
1427
  </question>';
1428
        $xmldata = xmlize($xml);
1429
 
1430
        $importer = new qformat_xml();
1431
        $q = $importer->import_truefalse($xmldata['question']);
1432
 
1433
        $expectedq = new \stdClass();
1434
        $expectedq->qtype = 'truefalse';
1435
        $expectedq->name = 'True false question';
1436
        $expectedq->questiontext = 'The answer is true.';
1437
        $expectedq->questiontextformat = FORMAT_HTML;
1438
        $expectedq->generalfeedback = 'General feedback: You should have chosen true.';
1439
        $expectedq->defaultmark = 1;
1440
        $expectedq->length = 1;
1441
        $expectedq->penalty = 1;
1442
        $expectedq->idnumber = 'TestIdNum1';
1443
 
1444
        $expectedq->feedbacktrue = array('text' => 'Well done!',
1445
                'format' => FORMAT_HTML);
1446
        $expectedq->feedbackfalse = array('text' => 'Doh!',
1447
                'format' => FORMAT_HTML);
1448
        $expectedq->correctanswer = true;
1449
 
1450
        $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1451
    }
1452
 
11 efrain 1453
    public function test_export_truefalse(): void {
1 efrain 1454
        $qdata = new \stdClass();
1455
        $qdata->id = 12;
1456
        $qdata->contextid = \context_system::instance()->id;
1457
        $qdata->qtype = 'truefalse';
1458
        $qdata->name = 'True false question';
1459
        $qdata->questiontext = 'The answer is true.';
1460
        $qdata->questiontextformat = FORMAT_HTML;
1461
        $qdata->generalfeedback = 'General feedback: You should have chosen true.';
1462
        $qdata->generalfeedbackformat = FORMAT_HTML;
1463
        $qdata->defaultmark = 1;
1464
        $qdata->length = 1;
1465
        $qdata->penalty = 1;
1466
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
1467
        $qdata->idnumber = null;
1468
 
1469
        $qdata->options = new \stdClass();
1470
        $qdata->options->answers = array(
1471
            1 => new question_answer(1, 'True', 1, 'Well done!', FORMAT_HTML),
1472
            2 => new question_answer(2, 'False', 0, 'Doh!', FORMAT_HTML),
1473
        );
1474
        $qdata->options->trueanswer = 1;
1475
        $qdata->options->falseanswer = 2;
1476
 
1477
        $exporter = new qformat_xml();
1478
        $xml = $exporter->writequestion($qdata);
1479
 
1480
        $expectedxml = '<!-- question: 12  -->
1481
  <question type="truefalse">
1482
    <name>
1483
      <text>True false question</text>
1484
    </name>
1485
    <questiontext format="html">
1486
      <text>The answer is true.</text>
1487
    </questiontext>
1488
    <generalfeedback format="html">
1489
      <text>General feedback: You should have chosen true.</text>
1490
    </generalfeedback>
1491
    <defaultgrade>1</defaultgrade>
1492
    <penalty>1</penalty>
1493
    <hidden>0</hidden>
1494
    <idnumber></idnumber>
1495
    <answer fraction="100" format="plain_text">
1496
      <text>true</text>
1497
      <feedback format="html">
1498
        <text>Well done!</text>
1499
      </feedback>
1500
    </answer>
1501
    <answer fraction="0" format="plain_text">
1502
      <text>false</text>
1503
      <feedback format="html">
1504
        <text>Doh!</text>
1505
      </feedback>
1506
    </answer>
1507
  </question>
1508
';
1509
 
1510
        $this->assert_same_xml($expectedxml, $xml);
1511
    }
1512
 
11 efrain 1513
    public function test_export_truefalse_with_idnumber(): void {
1 efrain 1514
        $qdata = new \stdClass();
1515
        $qdata->id = 12;
1516
        $qdata->contextid = \context_system::instance()->id;
1517
        $qdata->qtype = 'truefalse';
1518
        $qdata->name = 'True false question';
1519
        $qdata->questiontext = 'The answer is true.';
1520
        $qdata->questiontextformat = FORMAT_HTML;
1521
        $qdata->generalfeedback = 'General feedback: You should have chosen true.';
1522
        $qdata->generalfeedbackformat = FORMAT_HTML;
1523
        $qdata->defaultmark = 1;
1524
        $qdata->length = 1;
1525
        $qdata->penalty = 1;
1526
        $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY;
1527
        $qdata->idnumber = 'TestIDNum2';
1528
 
1529
        $qdata->options = new \stdClass();
1530
        $qdata->options->answers = array(
1531
                1 => new question_answer(1, 'True', 1, 'Well done!', FORMAT_HTML),
1532
                2 => new question_answer(2, 'False', 0, 'Doh!', FORMAT_HTML),
1533
        );
1534
        $qdata->options->trueanswer = 1;
1535
        $qdata->options->falseanswer = 2;
1536
 
1537
        $exporter = new qformat_xml();
1538
        $xml = $exporter->writequestion($qdata);
1539
 
1540
        $expectedxml = '<!-- question: 12  -->
1541
  <question type="truefalse">
1542
    <name>
1543
      <text>True false question</text>
1544
    </name>
1545
    <questiontext format="html">
1546
      <text>The answer is true.</text>
1547
    </questiontext>
1548
    <generalfeedback format="html">
1549
      <text>General feedback: You should have chosen true.</text>
1550
    </generalfeedback>
1551
    <defaultgrade>1</defaultgrade>
1552
    <penalty>1</penalty>
1553
    <hidden>0</hidden>
1554
    <idnumber>TestIDNum2</idnumber>
1555
    <answer fraction="100" format="plain_text">
1556
      <text>true</text>
1557
      <feedback format="html">
1558
        <text>Well done!</text>
1559
      </feedback>
1560
    </answer>
1561
    <answer fraction="0" format="plain_text">
1562
      <text>false</text>
1563
      <feedback format="html">
1564
        <text>Doh!</text>
1565
      </feedback>
1566
    </answer>
1567
  </question>
1568
';
1569
 
1570
        $this->assert_same_xml($expectedxml, $xml);
1571
    }
1572
 
11 efrain 1573
    public function test_import_multianswer(): void {
1 efrain 1574
        $xml = '  <question type="cloze">
1575
    <name>
1576
      <text>Simple multianswer</text>
1577
    </name>
1578
    <questiontext format="html">
1579
      <text><![CDATA[Complete this opening line of verse: "The {1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!} went to sea".]]></text>
1580
    </questiontext>
1581
    <generalfeedback format="html">
1582
      <text><![CDATA[General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".]]></text>
1583
    </generalfeedback>
1584
    <penalty>0.5</penalty>
1585
    <hidden>0</hidden>
1586
    <idnumber>id-101</idnumber>
1587
    <hint format="html">
1588
      <text>Hint 1</text>
1589
    </hint>
1590
    <hint format="html">
1591
      <text>Hint 2</text>
1592
    </hint>
1593
    <tags>
1594
      <tag><text>tagCloze</text></tag>
1595
      <tag><text>tagTest</text></tag>
1596
    </tags>
1597
  </question>
1598
';
1599
        $xmldata = xmlize($xml);
1600
 
1601
        $importer = new qformat_xml();
1602
        $q = $importer->import_multianswer($xmldata['question']);
1603
 
1604
        // Annoyingly, import works in a weird way (it duplicates code, rather
1605
        // than just calling save_question) so we cannot use
1606
        // \test_question_maker::get_question_form_data('multianswer', 'twosubq').
1607
        $expectedqa = new \stdClass();
1608
        $expectedqa->name = 'Simple multianswer';
1609
        $expectedqa->qtype = 'multianswer';
1610
        $expectedqa->questiontext = 'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
1611
        $expectedqa->idnumber = 'id-101';
1612
        $expectedqa->generalfeedback =
1613
                'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".';
1614
        $expectedqa->defaultmark = 2;
1615
        $expectedqa->penalty = 0.5;
1616
 
1617
        $expectedqa->hint = array(
1618
            array('text' => 'Hint 1', 'format' => FORMAT_HTML),
1619
            array('text' => 'Hint 2', 'format' => FORMAT_HTML),
1620
        );
1621
 
1622
        $sa = new \stdClass();
1623
 
1624
        $sa->questiontext = array('text' => '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}',
1625
                'format' => FORMAT_HTML, 'itemid' => null);
1626
        $sa->generalfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1627
        $sa->defaultmark = 1.0;
1628
        $sa->qtype = 'shortanswer';
1629
        $sa->usecase = 0;
1630
 
1631
        $sa->answer = array('Dog', 'Owl', '*');
1632
        $sa->fraction = array(0, 1, 0);
1633
        $sa->feedback = array(
1634
            array('text' => 'Wrong, silly!', 'format' => FORMAT_HTML, 'itemid' => null),
1635
            array('text' => 'Well done!',    'format' => FORMAT_HTML, 'itemid' => null),
1636
            array('text' => 'Wrong answer',  'format' => FORMAT_HTML, 'itemid' => null),
1637
        );
1638
 
1639
        $mc = new \stdClass();
1640
 
1641
        $mc->generalfeedback = '';
1642
        $mc->questiontext = array('text' => '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~' .
1643
                'Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}',
1644
                'format' => FORMAT_HTML, 'itemid' => null);
1645
        $mc->generalfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1646
        $mc->defaultmark = 1.0;
1647
        $mc->qtype = 'multichoice';
1648
 
1649
        $mc->layout = 0;
1650
        $mc->single = 1;
1651
        $mc->shuffleanswers = 0;
1652
        $mc->correctfeedback =          array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1653
        $mc->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1654
        $mc->incorrectfeedback =        array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1655
        $mc->answernumbering = 0;
1656
 
1657
        $mc->answer = array(
1658
            array('text' => 'Bow-wow',     'format' => FORMAT_HTML, 'itemid' => null),
1659
            array('text' => 'Wiggly worm', 'format' => FORMAT_HTML, 'itemid' => null),
1660
            array('text' => 'Pussy-cat',   'format' => FORMAT_HTML, 'itemid' => null),
1661
        );
1662
        $mc->fraction = array(0, 0, 1);
1663
        $mc->feedback = array(
1664
            array('text' => 'You seem to have a dog obsessions!', 'format' => FORMAT_HTML, 'itemid' => null),
1665
            array('text' => 'Now you are just being ridiculous!', 'format' => FORMAT_HTML, 'itemid' => null),
1666
            array('text' => 'Well done!',                         'format' => FORMAT_HTML, 'itemid' => null),
1667
        );
1668
 
1669
        $expectedqa->options = new \stdClass();
1670
        $expectedqa->options->questions = array(
1671
            1 => $sa,
1672
            2 => $mc,
1673
        );
1674
        $expectedqa->tags = array('tagCloze', 'tagTest');
1675
 
1676
        $this->assertEquals($expectedqa->hint, $q->hint);
1677
        $this->assertEquals($expectedqa->options->questions[1], $q->options->questions[1]);
1678
        $this->assertEquals($expectedqa->options->questions[2], $q->options->questions[2]);
1679
        $this->assert(new question_check_specified_fields_expectation($expectedqa), $q);
1680
    }
1681
 
11 efrain 1682
    public function test_export_multianswer(): void {
1 efrain 1683
        $qdata = \test_question_maker::get_question_data('multianswer', 'twosubq');
1684
        $qdata->contextid = \context_system::instance()->id;
1685
        $exporter = new qformat_xml();
1686
        $xml = $exporter->writequestion($qdata);
1687
 
1688
        $expectedxml = '<!-- question: 0  -->
1689
  <question type="cloze">
1690
    <name>
1691
      <text>Simple multianswer</text>
1692
    </name>
1693
    <questiontext format="html">
1694
      <text><![CDATA[Complete this opening line of verse: "The {1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!} went to sea".]]></text>
1695
    </questiontext>
1696
    <generalfeedback format="html">
1697
      <text><![CDATA[General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea]]></text>
1698
    </generalfeedback>
1699
    <penalty>0.3333333</penalty>
1700
    <hidden>0</hidden>
1701
    <idnumber></idnumber>
1702
    <hint format="html">
1703
      <text>Hint 1</text>
1704
    </hint>
1705
    <hint format="html">
1706
      <text>Hint 2</text>
1707
    </hint>
1708
  </question>
1709
';
1710
 
1711
        $this->assert_same_xml($expectedxml, $xml);
1712
    }
1713
 
11 efrain 1714
    public function test_export_multianswer_withdollars(): void {
1 efrain 1715
        $qdata = \test_question_maker::get_question_data('multianswer', 'dollarsigns');
1716
        $qdata->contextid = \context_system::instance()->id;
1717
        $exporter = new qformat_xml();
1718
        $xml = $exporter->writequestion($qdata);
1719
 
1720
        $expectedxml = '<!-- question: 0  -->
1721
  <question type="cloze">
1722
    <name>
1723
      <text>Multianswer with $s</text>
1724
    </name>
1725
    <questiontext format="html">
1726
      <text>Which is the right order? {1:MULTICHOICE:=y,y,$3~$3,y,y}</text>
1727
    </questiontext>
1728
    <generalfeedback format="html">
1729
      <text></text>
1730
    </generalfeedback>
1731
    <penalty>0.3333333</penalty>
1732
    <hidden>0</hidden>
1733
    <idnumber></idnumber>
1734
  </question>
1735
';
1736
 
1737
        $this->assert_same_xml($expectedxml, $xml);
1738
    }
1739
 
11 efrain 1740
    public function test_import_files_as_draft(): void {
1 efrain 1741
        $this->resetAfterTest();
1742
        $this->setAdminUser();
1743
 
1744
        $xml = <<<END
1745
<questiontext format="html">
1746
    <text><![CDATA[<p><a href="@@PLUGINFILE@@/moodle.txt">This text file</a> contains the word 'Moodle'.</p>]]></text>
1747
    <file name="moodle.txt" encoding="base64">TW9vZGxl</file>
1748
</questiontext>
1749
END;
1750
 
1751
        $textxml = xmlize($xml);
1752
        $qo = new \stdClass();
1753
 
1754
        $importer = new qformat_xml();
1755
        $draftitemid = $importer->import_files_as_draft($textxml['questiontext']['#']['file']);
1756
        $files = file_get_drafarea_files($draftitemid);
1757
 
1758
        $this->assertEquals(1, count($files->list));
1759
 
1760
        $file = $files->list[0];
1761
        $this->assertEquals('moodle.txt', $file->filename);
1762
        $this->assertEquals('/',          $file->filepath);
1763
        $this->assertEquals(6,            $file->size);
1764
    }
1765
 
11 efrain 1766
    public function test_import_truefalse_wih_files(): void {
1 efrain 1767
        $this->resetAfterTest();
1768
        $this->setAdminUser();
1769
 
1770
        $xml = '<question type="truefalse">
1771
    <name>
1772
      <text>truefalse</text>
1773
    </name>
1774
    <questiontext format="html">
1775
      <text><![CDATA[<p><a href="@@PLUGINFILE@@/myfolder/moodle.txt">This text file</a> contains the word Moodle.</p>]]></text>
1776
<file name="moodle.txt" path="/myfolder/" encoding="base64">TW9vZGxl</file>
1777
    </questiontext>
1778
    <generalfeedback format="html">
1779
      <text><![CDATA[<p>For further information, see the documentation about Moodle.</p>]]></text>
1780
</generalfeedback>
1781
    <defaultgrade>1.0000000</defaultgrade>
1782
    <penalty>1.0000000</penalty>
1783
    <hidden>0</hidden>
1784
    <answer fraction="100" format="moodle_auto_format">
1785
      <text>true</text>
1786
      <feedback format="html">
1787
        <text></text>
1788
      </feedback>
1789
    </answer>
1790
    <answer fraction="0" format="moodle_auto_format">
1791
      <text>false</text>
1792
      <feedback format="html">
1793
        <text></text>
1794
      </feedback>
1795
    </answer>
1796
  </question>';
1797
        $xmldata = xmlize($xml);
1798
 
1799
        $importer = new qformat_xml();
1800
        $q = $importer->import_truefalse($xmldata['question']);
1801
 
1802
        $draftitemid = $q->questiontextitemid;
1803
        $files = file_get_drafarea_files($draftitemid, '/myfolder/');
1804
 
1805
        $this->assertEquals(1, count($files->list));
1806
 
1807
        $file = $files->list[0];
1808
        $this->assertEquals('moodle.txt', $file->filename);
1809
        $this->assertEquals('/myfolder/', $file->filepath);
1810
        $this->assertEquals(6,            $file->size);
1811
    }
1812
 
11 efrain 1813
    public function test_create_dummy_question(): void {
1 efrain 1814
 
1815
        $testobject = new mock_qformat_xml();
1816
        $categoryname = 'name1';
1817
        $categoryinfo = new \stdClass();
1818
        $categoryinfo->info = 'info1';
1819
        $categoryinfo->infoformat = 'infoformat1';
1820
        $categoryinfo->idnumber = null;
1821
        $dummyquestion = $testobject->mock_create_dummy_question_representing_category($categoryname, $categoryinfo);
1822
 
1823
        $this->assertEquals('category', $dummyquestion->qtype);
1824
        $this->assertEquals($categoryname, $dummyquestion->category);
1825
        $this->assertEquals($categoryinfo->info, $dummyquestion->info);
1826
        $this->assertEquals($categoryinfo->infoformat, $dummyquestion->infoformat);
1827
        $this->assertEquals('Switch category to ' . $categoryname, $dummyquestion->name);
1828
        $this->assertEquals(0, $dummyquestion->id);
1829
        $this->assertEquals('', $dummyquestion->questiontextformat);
1830
        $this->assertEquals(0, $dummyquestion->contextid);
1831
    }
1832
}
1833
 
1834
/**
1835
 * Class mock_qformat_xml exists only to enable testing of the create dummy question category.
1836
 * @package    qformat_xml
1837
 * @copyright  2018 The Open University
1838
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1839
 */
1840
class mock_qformat_xml extends qformat_xml {
1841
    /**
1842
     * Make public an otherwise protected function.
1843
     * @param string $categoryname the name of the category
1844
     * @param object $categoryinfo description of the category
1845
     */
1846
    public function mock_create_dummy_question_representing_category(string $categoryname, $categoryinfo) {
1847
        return $this->create_dummy_question_representing_category($categoryname, $categoryinfo);
1848
    }
1849
}