478ab57d5eddee303303955bfbc5f8f5ce36131d
[moodle.git] / h5p / tests / generator_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Test class covering the h5p data generator class.
19 *
20 * @package    core_h5p
21 * @category   test
22 * @copyright  2019 Mihail Geshoski <mihail@moodle.com>
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
26 namespace core_h5p;
28 use core_h5p\local\library\autoloader;
30 defined('MOODLE_INTERNAL') || die();
32 /**
33 * Generator testcase for the core_grading generator.
34 *
35 * @package    core_h5p
36 * @category   test
37 * @copyright  2019 Mihail Geshoski <mihail@moodle.com>
38 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 * @runTestsInSeparateProcesses
40 */
41 class generator_testcase extends \advanced_testcase {
43     /**
44      * Tests set up.
45      */
46     protected function setUp() {
47         parent::setUp();
49         autoloader::register();
50     }
52     /**
53      * Test the returned data of generate_h5p_data() when the method is called without requesting
54      * creation of library files.
55      */
56     public function test_generate_h5p_data_no_files_created_return_data() {
57         global $DB;
59         $this->resetAfterTest();
61         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
63         $data = $generator->generate_h5p_data();
65         $mainlib = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']);
66         $lib1 = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']);
67         $lib2 = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']);
68         $lib3 = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']);
69         $lib4 = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']);
70         $lib5 = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']);
72         $h5p = $DB->get_record('h5p', ['mainlibraryid' => $mainlib->id]);
74         $expected = (object) [
75             'h5pcontent' => (object) array(
76                  'h5pid' => $h5p->id,
77                  'contentdependencies' => array($mainlib, $lib1, $lib2, $lib3, $lib4)
78             ),
79             'mainlib' => (object) array(
80                 'data' => $mainlib,
81                 'dependencies' => array($lib1, $lib2, $lib3)
82             ),
83             'lib1' => (object) array(
84                 'data' => $lib1,
85                 'dependencies' => array($lib2, $lib3, $lib4)
86             ),
87             'lib2' => (object) array(
88                 'data' => $lib2,
89                 'dependencies' => array()
90             ),
91             'lib3' => (object) array(
92                 'data' => $lib3,
93                 'dependencies' => array($lib5)
94             ),
95             'lib4' => (object) array(
96                 'data' => $lib4,
97                 'dependencies' => array()
98             ),
99             'lib5' => (object) array(
100                 'data' => $lib5,
101                 'dependencies' => array()
102             ),
103         ];
105         $this->assertEquals($expected, $data);
106     }
108     /**
109      * Test the returned data of generate_h5p_data() when the method requests
110      * creation of library files.
111      */
112     public function test_generate_h5p_data_files_created_return_data() {
113         global $DB;
115         $this->resetAfterTest();
117         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
119         $data = $generator->generate_h5p_data(true);
121         $mainlib = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']);
122         $lib1 = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']);
123         $lib2 = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']);
124         $lib3 = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']);
125         $lib4 = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']);
126         $lib5 = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']);
128         $h5p = $DB->get_record('h5p', ['mainlibraryid' => $mainlib->id]);
130         $expected = (object) [
131             'h5pcontent' => (object) array(
132                  'h5pid' => $h5p->id,
133                  'contentdependencies' => array($mainlib, $lib1, $lib2, $lib3, $lib4)
134             ),
135             'mainlib' => (object) array(
136                 'data' => $mainlib,
137                 'dependencies' => array($lib1, $lib2, $lib3)
138             ),
139             'lib1' => (object) array(
140                 'data' => $lib1,
141                 'dependencies' => array($lib2, $lib3, $lib4)
142             ),
143             'lib2' => (object) array(
144                 'data' => $lib2,
145                 'dependencies' => array()
146             ),
147             'lib3' => (object) array(
148                 'data' => $lib3,
149                 'dependencies' => array($lib5)
150             ),
151             'lib4' => (object) array(
152                 'data' => $lib4,
153                 'dependencies' => array()
154             ),
155             'lib5' => (object) array(
156                 'data' => $lib5,
157                 'dependencies' => array()
158             ),
159         ];
161         $this->assertEquals($expected, $data);
162     }
164     /**
165      * Test the behaviour of generate_h5p_data(). Test whether library files are created or not
166      * on filesystem depending what the method defines.
167      *
168      * @dataProvider test_generate_h5p_data_files_creation_provider
169      * @param bool $createlibraryfiles Whether to create library files on the filesystem
170      * @param bool $expected The expectation whether the files have been created or not
171      **/
172     public function test_generate_h5p_data_files_creation(bool $createlibraryfiles, bool $expected) {
173         global $DB;
175         $this->resetAfterTest();
177         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
178         $generator->generate_h5p_data($createlibraryfiles);
180         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']);
181         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']);
182         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']);
183         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']);
184         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']);
185         $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']);
187         foreach($libraries as $lib) {
188             // Return the created library files.
189             $libraryfiles = $DB->get_records('files',
190                 array(
191                     'component' => \core_h5p\file_storage::COMPONENT,
192                     'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA,
193                     'itemid' => $lib->id
194                 )
195             );
197             $haslibraryfiles = !empty($libraryfiles);
199             $this->assertEquals($expected, $haslibraryfiles);
200         }
201     }
203     /**
204      * Data provider for test_generate_h5p_data_files_creation().
205      *
206      * @return array
207      */
208     public function test_generate_h5p_data_files_creation_provider(): array {
209         return [
210             'Do not create library related files on the filesystem' => [
211                 false,
212                 false
213             ],
214             'Create library related files on the filesystem' => [
215                 true,
216                 true
217             ]
218         ];
219     }
221     /**
222      * Test the behaviour of create_library_record(). Test whether the library data is properly
223      * saved in the database.
224      */
225     public function test_create_library_record() {
226         $this->resetAfterTest();
228         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
230         $data = $generator->create_library_record('Library', 'Lib', 1, 2, 3, 'Semantics example', '/regex11/');
231         unset($data->id);
233         $expected = (object) [
234             'machinename' => 'Library',
235             'title' => 'Lib',
236             'majorversion' => '1',
237             'minorversion' => '2',
238             'patchversion' => '3',
239             'runnable' => '1',
240             'fullscreen' => '1',
241             'embedtypes' => '',
242             'preloadedjs' => 'js/example.js',
243             'preloadedcss' => 'css/example.css',
244             'droplibrarycss' => '',
245             'semantics' => 'Semantics example',
246             'addto' => '/regex11/',
247             'coremajor' => null,
248             'coreminor' => null,
249         ];
251         $this->assertEquals($expected, $data);
252     }
254     /**
255      * Test the behaviour of create_h5p_record(). Test whather the h5p content data is
256      * properly saved in the database.
257      *
258      * @dataProvider test_create_h5p_record_provider
259      * @param array $h5pdata The h5p content data
260      * @param \stdClass $expected The expected saved data
261      **/
262     public function test_create_h5p_record(array $h5pdata, \stdClass $expected) {
263         global $DB;
265         $this->resetAfterTest();
267         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
269         $h5pid = call_user_func_array([$generator, 'create_h5p_record'], $h5pdata);
271         $data = $DB->get_record('h5p', ['id' => $h5pid]);
272         unset($data->id);
273         unset($data->timecreated);
274         unset($data->timemodified);
276         $this->assertEquals($data, $expected);
277     }
279     /**
280      * Data provider for test_create_h5p_record().
281      *
282      * @return array
283      */
284     public function test_create_h5p_record_provider(): array {
285         $createdjsoncontent = json_encode(
286             array(
287                 'text' => '<p>Created dummy text<\/p>\n',
288                 'questions' => '<p>Test created question<\/p>\n'
289             )
290         );
292         $defaultjsoncontent = json_encode(
293             array(
294                 'text' => '<p>Dummy text<\/p>\n',
295                 'questions' => '<p>Test question<\/p>\n'
296             )
297         );
299         $createdfilteredcontent = json_encode(
300             array(
301                 'text' => 'Created dummy text',
302                 'questions' => 'Test created question'
303             )
304         );
306         $defaultfilteredcontent = json_encode(
307             array(
308                 'text' => 'Dummy text',
309                 'questions' => 'Test question'
310             )
311         );
313         return [
314             'Create h5p content record with set json content and set filtered content' => [
315                 [
316                     1,
317                     $createdjsoncontent,
318                     $createdfilteredcontent
319                 ],
320                 (object) array(
321                     'jsoncontent' => $createdjsoncontent,
322                     'mainlibraryid' => '1',
323                     'displayoptions' => '8',
324                     'pathnamehash' => sha1('pathname'),
325                     'contenthash' => sha1('content'),
326                     'filtered' => $createdfilteredcontent,
327                 )
328             ],
329             'Create h5p content record with set json content and default filtered content' => [
330                 [
331                     1,
332                     $createdjsoncontent,
333                     null
334                 ],
335                 (object) array(
336                     'jsoncontent' => $createdjsoncontent,
337                     'mainlibraryid' => '1',
338                     'displayoptions' => '8',
339                     'pathnamehash' => sha1('pathname'),
340                     'contenthash' => sha1('content'),
341                     'filtered' => $defaultfilteredcontent,
342                 )
343             ],
344             'Create h5p content record with default json content and set filtered content' => [
345                 [
346                     1,
347                     null,
348                     $createdfilteredcontent
349                 ],
350                 (object) array(
351                     'jsoncontent' => $defaultjsoncontent,
352                     'mainlibraryid' => '1',
353                     'displayoptions' => '8',
354                     'pathnamehash' => sha1('pathname'),
355                     'contenthash' => sha1('content'),
356                     'filtered' => $createdfilteredcontent,
357                 )
358             ],
359             'Create h5p content record with default json content and default filtered content' => [
360                 [
361                     1,
362                     null,
363                     null
364                 ],
365                 (object) array(
366                     'jsoncontent' => $defaultjsoncontent,
367                     'mainlibraryid' => '1',
368                     'displayoptions' => '8',
369                     'pathnamehash' => sha1('pathname'),
370                     'contenthash' => sha1('content'),
371                     'filtered' => $defaultfilteredcontent,
372                 )
373             ]
374         ];
375     }
377     /**
378      * Test the behaviour of create_contents_libraries_record(). Test whether the contents libraries
379      * are properly saved in the database.
380      *
381      * @dataProvider test_create_contents_libraries_record_provider
382      * @param array $contentslibrariestdata The h5p contents libraries data.
383      * @param \stdClass $expected The expected saved data.
384      **/
385     public function test_create_contents_libraries_record(array $contentslibrariestdata, \stdClass $expected) {
386         global $DB;
388         $this->resetAfterTest();
390         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
392         $contentlibid = call_user_func_array([$generator, 'create_contents_libraries_record'], $contentslibrariestdata);
394         $data = $DB->get_record('h5p_contents_libraries', ['id' => $contentlibid]);
395         unset($data->id);
397         $this->assertEquals($data, $expected);
398     }
400     /**
401      * Data provider for test_create_contents_libraries_record().
402      *
403      * @return array
404      */
405     public function test_create_contents_libraries_record_provider(): array {
406         return [
407             'Create h5p content library with set dependency type' => [
408                 [
409                     1,
410                     1,
411                     'dynamic'
412                 ],
413                 (object) array(
414                     'h5pid' => '1',
415                     'libraryid' => '1',
416                     'dependencytype' => 'dynamic',
417                     'dropcss' => '0',
418                     'weight' => '1'
419                 )
420             ],
421             'Create h5p content library with a default dependency type' => [
422                 [
423                     1,
424                     1
425                 ],
426                 (object) array(
427                     'h5pid' => '1',
428                     'libraryid' => '1',
429                     'dependencytype' => 'preloaded',
430                     'dropcss' => '0',
431                     'weight' => '1'
432                 )
433             ]
434         ];
435     }
437     /**
438      * Test the behaviour of create_library_dependency_record(). Test whether the contents libraries
439      * are properly saved in the database.
440      *
441      * @dataProvider test_create_library_dependency_record_provider
442      * @param array $librarydependencydata The library dependency data.
443      * @param \stdClass $expected The expected saved data.
444      **/
445     public function test_create_library_dependency_record(array $librarydependencydata, \stdClass $expected) {
446         global $DB;
448         $this->resetAfterTest();
450         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
452         $contentlibid = call_user_func_array([$generator, 'create_library_dependency_record'], $librarydependencydata);
454         $data = $DB->get_record('h5p_library_dependencies', ['id' => $contentlibid]);
455         unset($data->id);
457         $this->assertEquals($data, $expected);
458     }
460     /**
461      * Data provider for test_create_library_dependency_record().
462      *
463      * @return array
464      */
465     public function test_create_library_dependency_record_provider(): array {
466         return [
467             'Create h5p library dependency with set dependency type' => [
468                 [
469                     1,
470                     1,
471                     'dynamic'
472                 ],
473                 (object) array(
474                     'libraryid' => '1',
475                     'requiredlibraryid' => '1',
476                     'dependencytype' => 'dynamic'
477                 )
478             ],
479             'Create h5p library dependency with default dependency type' => [
480                 [
481                     1,
482                     1
483                 ],
484                 (object) array(
485                     'libraryid' => '1',
486                     'requiredlibraryid' => '1',
487                     'dependencytype' => 'preloaded'
488                 )
489             ]
490         ];
491     }
493     /**
494      * Test the behaviour of create_content_file(). Test whether a file belonging to a content is created.
495      *
496      * @dataProvider test_create_content_file_provider
497      * @param array $filedata Data from the file to be created.
498      * @param array $expecteddata Data expected.Data from the file to be created.
499      */
500     public function test_create_content_file($filedata, $expecteddata): void {
501         $this->resetAfterTest();
503         $generator = self::getDataGenerator()->get_plugin_generator('core_h5p');
505         if ($expecteddata[1] === 'exception') {
506             $this->expectException('coding_exception');
507         }
508         call_user_func_array([$generator, 'create_content_file'], $filedata);
510         $systemcontext = \context_system::instance();
511         $filearea = $filedata[1];
512         $filepath = '/'. dirname($filedata[0]). '/';
513         $filename = basename($filedata[0]);
514         $itemid = $expecteddata[0];
516         $fs = new \file_storage();
517         $exists = $fs->file_exists($systemcontext->id, file_storage::COMPONENT, $filearea, $itemid, $filepath,
518             $filename);
519         if ($expecteddata[1] === true) {
520             $this->assertTrue($exists);
521         } else if ($expecteddata[1] === false) {
522             $this->assertFalse($exists);
523         }
524     }
526     /**
527      * Data provider for test_create_content_file(). Data from different files to be created.
528      *
529      * @return array
530      **/
531     public function test_create_content_file_provider(): array {
532         return [
533             'Create file in content with id 4' => [
534                 [
535                     'images/img1.png',
536                     'content',
537                     4
538                 ],
539                 [
540                     4,
541                     true
542                 ]
543             ],
544             'Create file in the editor' => [
545                 [
546                     'images/img1.png',
547                     'editor'
548                 ],
549                 [
550                     0,
551                     true
552                 ]
553             ],
554             'Create file in content without id' => [
555                 [
556                     'images/img1.png',
557                     'content'
558                 ],
559                 [
560                     0,
561                     'exception'
562                 ]
563             ]
564         ];
565     }