MDL-68921 core_h5p: Add H5P libraries metadata settings
[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             'metadatasettings' => null,
250         ];
252         $this->assertEquals($expected, $data);
253     }
255     /**
256      * Test the behaviour of create_h5p_record(). Test whather the h5p content data is
257      * properly saved in the database.
258      *
259      * @dataProvider test_create_h5p_record_provider
260      * @param array $h5pdata The h5p content data
261      * @param \stdClass $expected The expected saved data
262      **/
263     public function test_create_h5p_record(array $h5pdata, \stdClass $expected) {
264         global $DB;
266         $this->resetAfterTest();
268         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
270         $h5pid = call_user_func_array([$generator, 'create_h5p_record'], $h5pdata);
272         $data = $DB->get_record('h5p', ['id' => $h5pid]);
273         unset($data->id);
274         unset($data->timecreated);
275         unset($data->timemodified);
277         $this->assertEquals($data, $expected);
278     }
280     /**
281      * Data provider for test_create_h5p_record().
282      *
283      * @return array
284      */
285     public function test_create_h5p_record_provider(): array {
286         $createdjsoncontent = json_encode(
287             array(
288                 'text' => '<p>Created dummy text<\/p>\n',
289                 'questions' => '<p>Test created question<\/p>\n'
290             )
291         );
293         $defaultjsoncontent = json_encode(
294             array(
295                 'text' => '<p>Dummy text<\/p>\n',
296                 'questions' => '<p>Test question<\/p>\n'
297             )
298         );
300         $createdfilteredcontent = json_encode(
301             array(
302                 'text' => 'Created dummy text',
303                 'questions' => 'Test created question'
304             )
305         );
307         $defaultfilteredcontent = json_encode(
308             array(
309                 'text' => 'Dummy text',
310                 'questions' => 'Test question'
311             )
312         );
314         return [
315             'Create h5p content record with set json content and set filtered content' => [
316                 [
317                     1,
318                     $createdjsoncontent,
319                     $createdfilteredcontent
320                 ],
321                 (object) array(
322                     'jsoncontent' => $createdjsoncontent,
323                     'mainlibraryid' => '1',
324                     'displayoptions' => '8',
325                     'pathnamehash' => sha1('pathname'),
326                     'contenthash' => sha1('content'),
327                     'filtered' => $createdfilteredcontent,
328                 )
329             ],
330             'Create h5p content record with set json content and default filtered content' => [
331                 [
332                     1,
333                     $createdjsoncontent,
334                     null
335                 ],
336                 (object) array(
337                     'jsoncontent' => $createdjsoncontent,
338                     'mainlibraryid' => '1',
339                     'displayoptions' => '8',
340                     'pathnamehash' => sha1('pathname'),
341                     'contenthash' => sha1('content'),
342                     'filtered' => $defaultfilteredcontent,
343                 )
344             ],
345             'Create h5p content record with default json content and set filtered content' => [
346                 [
347                     1,
348                     null,
349                     $createdfilteredcontent
350                 ],
351                 (object) array(
352                     'jsoncontent' => $defaultjsoncontent,
353                     'mainlibraryid' => '1',
354                     'displayoptions' => '8',
355                     'pathnamehash' => sha1('pathname'),
356                     'contenthash' => sha1('content'),
357                     'filtered' => $createdfilteredcontent,
358                 )
359             ],
360             'Create h5p content record with default json content and default filtered content' => [
361                 [
362                     1,
363                     null,
364                     null
365                 ],
366                 (object) array(
367                     'jsoncontent' => $defaultjsoncontent,
368                     'mainlibraryid' => '1',
369                     'displayoptions' => '8',
370                     'pathnamehash' => sha1('pathname'),
371                     'contenthash' => sha1('content'),
372                     'filtered' => $defaultfilteredcontent,
373                 )
374             ]
375         ];
376     }
378     /**
379      * Test the behaviour of create_contents_libraries_record(). Test whether the contents libraries
380      * are properly saved in the database.
381      *
382      * @dataProvider test_create_contents_libraries_record_provider
383      * @param array $contentslibrariestdata The h5p contents libraries data.
384      * @param \stdClass $expected The expected saved data.
385      **/
386     public function test_create_contents_libraries_record(array $contentslibrariestdata, \stdClass $expected) {
387         global $DB;
389         $this->resetAfterTest();
391         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
393         $contentlibid = call_user_func_array([$generator, 'create_contents_libraries_record'], $contentslibrariestdata);
395         $data = $DB->get_record('h5p_contents_libraries', ['id' => $contentlibid]);
396         unset($data->id);
398         $this->assertEquals($data, $expected);
399     }
401     /**
402      * Data provider for test_create_contents_libraries_record().
403      *
404      * @return array
405      */
406     public function test_create_contents_libraries_record_provider(): array {
407         return [
408             'Create h5p content library with set dependency type' => [
409                 [
410                     1,
411                     1,
412                     'dynamic'
413                 ],
414                 (object) array(
415                     'h5pid' => '1',
416                     'libraryid' => '1',
417                     'dependencytype' => 'dynamic',
418                     'dropcss' => '0',
419                     'weight' => '1'
420                 )
421             ],
422             'Create h5p content library with a default dependency type' => [
423                 [
424                     1,
425                     1
426                 ],
427                 (object) array(
428                     'h5pid' => '1',
429                     'libraryid' => '1',
430                     'dependencytype' => 'preloaded',
431                     'dropcss' => '0',
432                     'weight' => '1'
433                 )
434             ]
435         ];
436     }
438     /**
439      * Test the behaviour of create_library_dependency_record(). Test whether the contents libraries
440      * are properly saved in the database.
441      *
442      * @dataProvider test_create_library_dependency_record_provider
443      * @param array $librarydependencydata The library dependency data.
444      * @param \stdClass $expected The expected saved data.
445      **/
446     public function test_create_library_dependency_record(array $librarydependencydata, \stdClass $expected) {
447         global $DB;
449         $this->resetAfterTest();
451         $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
453         $contentlibid = call_user_func_array([$generator, 'create_library_dependency_record'], $librarydependencydata);
455         $data = $DB->get_record('h5p_library_dependencies', ['id' => $contentlibid]);
456         unset($data->id);
458         $this->assertEquals($data, $expected);
459     }
461     /**
462      * Data provider for test_create_library_dependency_record().
463      *
464      * @return array
465      */
466     public function test_create_library_dependency_record_provider(): array {
467         return [
468             'Create h5p library dependency with set dependency type' => [
469                 [
470                     1,
471                     1,
472                     'dynamic'
473                 ],
474                 (object) array(
475                     'libraryid' => '1',
476                     'requiredlibraryid' => '1',
477                     'dependencytype' => 'dynamic'
478                 )
479             ],
480             'Create h5p library dependency with default dependency type' => [
481                 [
482                     1,
483                     1
484                 ],
485                 (object) array(
486                     'libraryid' => '1',
487                     'requiredlibraryid' => '1',
488                     'dependencytype' => 'preloaded'
489                 )
490             ]
491         ];
492     }
494     /**
495      * Test the behaviour of create_content_file(). Test whether a file belonging to a content is created.
496      *
497      * @dataProvider test_create_content_file_provider
498      * @param array $filedata Data from the file to be created.
499      * @param array $expecteddata Data expected.Data from the file to be created.
500      */
501     public function test_create_content_file($filedata, $expecteddata): void {
502         $this->resetAfterTest();
504         $generator = self::getDataGenerator()->get_plugin_generator('core_h5p');
506         if ($expecteddata[1] === 'exception') {
507             $this->expectException('coding_exception');
508         }
509         call_user_func_array([$generator, 'create_content_file'], $filedata);
511         $systemcontext = \context_system::instance();
512         $filearea = $filedata[1];
513         $filepath = '/'. dirname($filedata[0]). '/';
514         $filename = basename($filedata[0]);
515         $itemid = $expecteddata[0];
517         $fs = new \file_storage();
518         $exists = $fs->file_exists($systemcontext->id, file_storage::COMPONENT, $filearea, $itemid, $filepath,
519             $filename);
520         if ($expecteddata[1] === true) {
521             $this->assertTrue($exists);
522         } else if ($expecteddata[1] === false) {
523             $this->assertFalse($exists);
524         }
525     }
527     /**
528      * Data provider for test_create_content_file(). Data from different files to be created.
529      *
530      * @return array
531      **/
532     public function test_create_content_file_provider(): array {
533         return [
534             'Create file in content with id 4' => [
535                 [
536                     'images/img1.png',
537                     'content',
538                     4
539                 ],
540                 [
541                     4,
542                     true
543                 ]
544             ],
545             'Create file in the editor' => [
546                 [
547                     'images/img1.png',
548                     'editor'
549                 ],
550                 [
551                     0,
552                     true
553                 ]
554             ],
555             'Create file in content without id' => [
556                 [
557                     'images/img1.png',
558                     'content'
559                 ],
560                 [
561                     0,
562                     'exception'
563                 ]
564             ]
565         ];
566     }