Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core_h5p; 18 19 use core_h5p\local\library\autoloader; 20 21 /** 22 * Test class covering the h5p data generator class. 23 * 24 * @package core_h5p 25 * @category test 26 * @copyright 2019 Mihail Geshoski <mihail@moodle.com> 27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 28 * @runTestsInSeparateProcesses 29 * @covers \core_h5p_generator 30 */ 31 class generator_test extends \advanced_testcase { 32 33 /** 34 * Tests set up. 35 */ 36 protected function setUp(): void { 37 parent::setUp(); 38 39 autoloader::register(); 40 } 41 42 /** 43 * Test the returned data of generate_h5p_data() when the method is called without requesting 44 * creation of library files. 45 */ 46 public function test_generate_h5p_data_no_files_created_return_data() { 47 global $DB; 48 49 $this->resetAfterTest(); 50 51 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 52 53 $data = $generator->generate_h5p_data(); 54 55 $mainlib = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']); 56 $lib1 = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']); 57 $lib2 = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']); 58 $lib3 = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']); 59 $lib4 = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']); 60 $lib5 = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']); 61 62 $h5p = $DB->get_record('h5p', ['mainlibraryid' => $mainlib->id]); 63 64 $expected = (object) [ 65 'h5pcontent' => (object) array( 66 'h5pid' => $h5p->id, 67 'contentdependencies' => array($mainlib, $lib1, $lib2, $lib3, $lib4) 68 ), 69 'mainlib' => (object) array( 70 'data' => $mainlib, 71 'dependencies' => array($lib1, $lib2, $lib3) 72 ), 73 'lib1' => (object) array( 74 'data' => $lib1, 75 'dependencies' => array($lib2, $lib3, $lib4) 76 ), 77 'lib2' => (object) array( 78 'data' => $lib2, 79 'dependencies' => array() 80 ), 81 'lib3' => (object) array( 82 'data' => $lib3, 83 'dependencies' => array($lib5) 84 ), 85 'lib4' => (object) array( 86 'data' => $lib4, 87 'dependencies' => array() 88 ), 89 'lib5' => (object) array( 90 'data' => $lib5, 91 'dependencies' => array() 92 ), 93 ]; 94 95 $this->assertEquals($expected, $data); 96 } 97 98 /** 99 * Test the returned data of generate_h5p_data() when the method requests 100 * creation of library files. 101 */ 102 public function test_generate_h5p_data_files_created_return_data() { 103 global $DB; 104 105 $this->resetAfterTest(); 106 107 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 108 109 $data = $generator->generate_h5p_data(true); 110 111 $mainlib = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']); 112 $lib1 = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']); 113 $lib2 = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']); 114 $lib3 = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']); 115 $lib4 = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']); 116 $lib5 = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']); 117 118 $h5p = $DB->get_record('h5p', ['mainlibraryid' => $mainlib->id]); 119 120 $expected = (object) [ 121 'h5pcontent' => (object) array( 122 'h5pid' => $h5p->id, 123 'contentdependencies' => array($mainlib, $lib1, $lib2, $lib3, $lib4) 124 ), 125 'mainlib' => (object) array( 126 'data' => $mainlib, 127 'dependencies' => array($lib1, $lib2, $lib3) 128 ), 129 'lib1' => (object) array( 130 'data' => $lib1, 131 'dependencies' => array($lib2, $lib3, $lib4) 132 ), 133 'lib2' => (object) array( 134 'data' => $lib2, 135 'dependencies' => array() 136 ), 137 'lib3' => (object) array( 138 'data' => $lib3, 139 'dependencies' => array($lib5) 140 ), 141 'lib4' => (object) array( 142 'data' => $lib4, 143 'dependencies' => array() 144 ), 145 'lib5' => (object) array( 146 'data' => $lib5, 147 'dependencies' => array() 148 ), 149 ]; 150 151 $this->assertEquals($expected, $data); 152 } 153 154 /** 155 * Test the behaviour of generate_h5p_data(). Test whether library files are created or not 156 * on filesystem depending what the method defines. 157 * 158 * @dataProvider generate_h5p_data_files_creation_provider 159 * @param bool $createlibraryfiles Whether to create library files on the filesystem 160 * @param bool $expected The expectation whether the files have been created or not 161 **/ 162 public function test_generate_h5p_data_files_creation(bool $createlibraryfiles, bool $expected) { 163 global $DB; 164 165 $this->resetAfterTest(); 166 167 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 168 $generator->generate_h5p_data($createlibraryfiles); 169 170 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']); 171 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']); 172 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']); 173 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']); 174 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']); 175 $libraries[] = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']); 176 177 foreach($libraries as $lib) { 178 // Return the created library files. 179 $libraryfiles = $DB->get_records('files', 180 array( 181 'component' => \core_h5p\file_storage::COMPONENT, 182 'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA, 183 'itemid' => $lib->id 184 ) 185 ); 186 187 $haslibraryfiles = !empty($libraryfiles); 188 189 $this->assertEquals($expected, $haslibraryfiles); 190 } 191 } 192 193 /** 194 * Data provider for test_generate_h5p_data_files_creation(). 195 * 196 * @return array 197 */ 198 public function generate_h5p_data_files_creation_provider(): array { 199 return [ 200 'Do not create library related files on the filesystem' => [ 201 false, 202 false 203 ], 204 'Create library related files on the filesystem' => [ 205 true, 206 true 207 ] 208 ]; 209 } 210 211 /** 212 * Test the returned data of generate_h5p_data() when the method requests 213 * creation of H5P file and xAPI states. 214 * 215 * @dataProvider generate_h5p_data_xapistates_provider 216 * @param array|null $filerecord 217 */ 218 public function test_generate_h5p_data_xapistates(?array $filerecord) { 219 global $DB; 220 221 $this->resetAfterTest(); 222 223 /** @var \core_h5p_generator $generator */ 224 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 225 $course = $this->getDataGenerator()->create_course(); 226 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 227 $this->setUser($user); 228 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 229 $activitycontext = \context_module::instance($activity->cmid); 230 if ($filerecord) { 231 $filerecord['contextid'] = $activitycontext->id; 232 $filerecord['component'] = 'mod_h5pactivity'; 233 $filerecord['filearea'] = 'package'; 234 $filerecord['itemid'] = 0; 235 $filerecord['filepath'] = '/'; 236 $filerecord['filepath'] = '/'; 237 $filerecord['filename'] = 'dummy.h5p'; 238 } 239 240 $data = $generator->generate_h5p_data(false, $filerecord); 241 242 $mainlib = $DB->get_record('h5p_libraries', ['machinename' => 'MainLibrary']); 243 $lib1 = $DB->get_record('h5p_libraries', ['machinename' => 'Library1']); 244 $lib2 = $DB->get_record('h5p_libraries', ['machinename' => 'Library2']); 245 $lib3 = $DB->get_record('h5p_libraries', ['machinename' => 'Library3']); 246 $lib4 = $DB->get_record('h5p_libraries', ['machinename' => 'Library4']); 247 $lib5 = $DB->get_record('h5p_libraries', ['machinename' => 'Library5']); 248 249 $h5p = $DB->get_record('h5p', ['mainlibraryid' => $mainlib->id]); 250 251 $expected = (object) [ 252 'h5pcontent' => (object) [ 253 'h5pid' => $h5p->id, 254 'contentdependencies' => [$mainlib, $lib1, $lib2, $lib3, $lib4], 255 ], 256 'mainlib' => (object) [ 257 'data' => $mainlib, 258 'dependencies' => [$lib1, $lib2, $lib3], 259 ], 260 'lib1' => (object) [ 261 'data' => $lib1, 262 'dependencies' => [$lib2, $lib3, $lib4], 263 ], 264 'lib2' => (object) [ 265 'data' => $lib2, 266 'dependencies' => [], 267 ], 268 'lib3' => (object) [ 269 'data' => $lib3, 270 'dependencies' => [$lib5], 271 ], 272 'lib4' => (object) [ 273 'data' => $lib4, 274 'dependencies' => [], 275 ], 276 'lib5' => (object) [ 277 'data' => $lib5, 278 'dependencies' => [], 279 ], 280 ]; 281 282 $this->assertEquals($expected, $data); 283 if ($filerecord) { 284 // Confirm the H5P file has been created (when $filerecord is not empty). 285 $fs = get_file_storage(); 286 $this->assertNotFalse($fs->get_file_by_hash($h5p->pathnamehash)); 287 // Confirm xAPI state has been created when $filerecord['addxapistate'] is given. 288 if (array_key_exists('addxapistate', $filerecord) && $filerecord['addxapistate']) { 289 $this->assertEquals(1, $DB->count_records('xapi_states')); 290 } else { 291 $this->assertEquals(0, $DB->count_records('xapi_states')); 292 } 293 } else { 294 // Confirm the H5P file doesn't exist when $filerecord is null. 295 $fs = get_file_storage(); 296 $this->assertFalse($fs->get_file_by_hash($h5p->pathnamehash)); 297 // Confirm xAPI state hasn't been created when $filerecord is null. 298 $this->assertEquals(0, $DB->count_records('xapi_states')); 299 } 300 } 301 302 /** 303 * Data provider for test_generate_h5p_data_xapistates(). 304 * 305 * @return array 306 */ 307 public function generate_h5p_data_xapistates_provider(): array { 308 return [ 309 'Do not create the file nor xAPI states' => [ 310 'filerecord' => null, 311 ], 312 'Create the H5P file but not create any xAPI state' => [ 313 'filerecord' => [ 314 'addxapistate' => false, 315 ], 316 ], 317 'Create the H5P file and the xAPI state' => [ 318 'filerecord' => [ 319 'addxapistate' => true, 320 ], 321 ], 322 ]; 323 } 324 325 /** 326 * Test the behaviour of create_library_record(). Test whether the library data is properly 327 * saved in the database. 328 */ 329 public function test_create_library_record() { 330 $this->resetAfterTest(); 331 332 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 333 334 $data = $generator->create_library_record( 335 'Library', 'Lib', 1, 2, 3, 'Semantics example', '/regex11/', 'http://tutorial.org/', 'http://example.org/' 336 ); 337 unset($data->id); 338 339 $expected = (object) [ 340 'machinename' => 'Library', 341 'title' => 'Lib', 342 'majorversion' => '1', 343 'minorversion' => '2', 344 'patchversion' => '3', 345 'runnable' => '1', 346 'fullscreen' => '1', 347 'embedtypes' => '', 348 'preloadedjs' => 'js/example.js', 349 'preloadedcss' => 'css/example.css', 350 'droplibrarycss' => '', 351 'semantics' => 'Semantics example', 352 'addto' => '/regex11/', 353 'tutorial' => 'http://tutorial.org/', 354 'example' => 'http://example.org/', 355 'coremajor' => null, 356 'coreminor' => null, 357 'metadatasettings' => null, 358 'enabled' => 1, 359 ]; 360 361 $this->assertEquals($expected, $data); 362 } 363 364 /** 365 * Test the behaviour of create_h5p_record(). Test whather the h5p content data is 366 * properly saved in the database. 367 * 368 * @dataProvider create_h5p_record_provider 369 * @param array $h5pdata The h5p content data 370 * @param \stdClass $expected The expected saved data 371 **/ 372 public function test_create_h5p_record(array $h5pdata, \stdClass $expected) { 373 global $DB; 374 375 $this->resetAfterTest(); 376 377 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 378 379 $h5pid = call_user_func_array([$generator, 'create_h5p_record'], $h5pdata); 380 381 $data = $DB->get_record('h5p', ['id' => $h5pid]); 382 unset($data->id); 383 unset($data->timecreated); 384 unset($data->timemodified); 385 386 $this->assertEquals($data, $expected); 387 } 388 389 /** 390 * Data provider for test_create_h5p_record(). 391 * 392 * @return array 393 */ 394 public function create_h5p_record_provider(): array { 395 $createdjsoncontent = json_encode( 396 array( 397 'text' => '<p>Created dummy text<\/p>\n', 398 'questions' => '<p>Test created question<\/p>\n' 399 ) 400 ); 401 402 $defaultjsoncontent = json_encode( 403 array( 404 'text' => '<p>Dummy text<\/p>\n', 405 'questions' => '<p>Test question<\/p>\n' 406 ) 407 ); 408 409 $createdfilteredcontent = json_encode( 410 array( 411 'text' => 'Created dummy text', 412 'questions' => 'Test created question' 413 ) 414 ); 415 416 $defaultfilteredcontent = json_encode( 417 array( 418 'text' => 'Dummy text', 419 'questions' => 'Test question' 420 ) 421 ); 422 423 return [ 424 'Create h5p content record with set json content and set filtered content' => [ 425 [ 426 1, 427 $createdjsoncontent, 428 $createdfilteredcontent 429 ], 430 (object) array( 431 'jsoncontent' => $createdjsoncontent, 432 'mainlibraryid' => '1', 433 'displayoptions' => '8', 434 'pathnamehash' => sha1('pathname'), 435 'contenthash' => sha1('content'), 436 'filtered' => $createdfilteredcontent, 437 ) 438 ], 439 'Create h5p content record with set json content and default filtered content' => [ 440 [ 441 1, 442 $createdjsoncontent, 443 null 444 ], 445 (object) array( 446 'jsoncontent' => $createdjsoncontent, 447 'mainlibraryid' => '1', 448 'displayoptions' => '8', 449 'pathnamehash' => sha1('pathname'), 450 'contenthash' => sha1('content'), 451 'filtered' => $defaultfilteredcontent, 452 ) 453 ], 454 'Create h5p content record with default json content and set filtered content' => [ 455 [ 456 1, 457 null, 458 $createdfilteredcontent 459 ], 460 (object) array( 461 'jsoncontent' => $defaultjsoncontent, 462 'mainlibraryid' => '1', 463 'displayoptions' => '8', 464 'pathnamehash' => sha1('pathname'), 465 'contenthash' => sha1('content'), 466 'filtered' => $createdfilteredcontent, 467 ) 468 ], 469 'Create h5p content record with default json content and default filtered content' => [ 470 [ 471 1, 472 null, 473 null 474 ], 475 (object) array( 476 'jsoncontent' => $defaultjsoncontent, 477 'mainlibraryid' => '1', 478 'displayoptions' => '8', 479 'pathnamehash' => sha1('pathname'), 480 'contenthash' => sha1('content'), 481 'filtered' => $defaultfilteredcontent, 482 ) 483 ] 484 ]; 485 } 486 487 /** 488 * Test the behaviour of create_contents_libraries_record(). Test whether the contents libraries 489 * are properly saved in the database. 490 * 491 * @dataProvider create_contents_libraries_record_provider 492 * @param array $contentslibrariestdata The h5p contents libraries data. 493 * @param \stdClass $expected The expected saved data. 494 **/ 495 public function test_create_contents_libraries_record(array $contentslibrariestdata, \stdClass $expected) { 496 global $DB; 497 498 $this->resetAfterTest(); 499 500 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 501 502 $contentlibid = call_user_func_array([$generator, 'create_contents_libraries_record'], $contentslibrariestdata); 503 504 $data = $DB->get_record('h5p_contents_libraries', ['id' => $contentlibid]); 505 unset($data->id); 506 507 $this->assertEquals($data, $expected); 508 } 509 510 /** 511 * Data provider for test_create_contents_libraries_record(). 512 * 513 * @return array 514 */ 515 public function create_contents_libraries_record_provider(): array { 516 return [ 517 'Create h5p content library with set dependency type' => [ 518 [ 519 1, 520 1, 521 'dynamic' 522 ], 523 (object) array( 524 'h5pid' => '1', 525 'libraryid' => '1', 526 'dependencytype' => 'dynamic', 527 'dropcss' => '0', 528 'weight' => '1' 529 ) 530 ], 531 'Create h5p content library with a default dependency type' => [ 532 [ 533 1, 534 1 535 ], 536 (object) array( 537 'h5pid' => '1', 538 'libraryid' => '1', 539 'dependencytype' => 'preloaded', 540 'dropcss' => '0', 541 'weight' => '1' 542 ) 543 ] 544 ]; 545 } 546 547 /** 548 * Test the behaviour of create_library_dependency_record(). Test whether the contents libraries 549 * are properly saved in the database. 550 * 551 * @dataProvider create_library_dependency_record_provider 552 * @param array $librarydependencydata The library dependency data. 553 * @param \stdClass $expected The expected saved data. 554 **/ 555 public function test_create_library_dependency_record(array $librarydependencydata, \stdClass $expected) { 556 global $DB; 557 558 $this->resetAfterTest(); 559 560 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 561 562 $contentlibid = call_user_func_array([$generator, 'create_library_dependency_record'], $librarydependencydata); 563 564 $data = $DB->get_record('h5p_library_dependencies', ['id' => $contentlibid]); 565 unset($data->id); 566 567 $this->assertEquals($data, $expected); 568 } 569 570 /** 571 * Data provider for test_create_library_dependency_record(). 572 * 573 * @return array 574 */ 575 public function create_library_dependency_record_provider(): array { 576 return [ 577 'Create h5p library dependency with set dependency type' => [ 578 [ 579 1, 580 1, 581 'dynamic' 582 ], 583 (object) array( 584 'libraryid' => '1', 585 'requiredlibraryid' => '1', 586 'dependencytype' => 'dynamic' 587 ) 588 ], 589 'Create h5p library dependency with default dependency type' => [ 590 [ 591 1, 592 1 593 ], 594 (object) array( 595 'libraryid' => '1', 596 'requiredlibraryid' => '1', 597 'dependencytype' => 'preloaded' 598 ) 599 ] 600 ]; 601 } 602 603 /** 604 * Test the behaviour of create_content_file(). Test whether a file belonging to a content is created. 605 * 606 * @dataProvider create_content_file_provider 607 * @param array $filedata Data from the file to be created. 608 * @param array $expecteddata Data expected.Data from the file to be created. 609 */ 610 public function test_create_content_file($filedata, $expecteddata): void { 611 $this->resetAfterTest(); 612 613 $generator = self::getDataGenerator()->get_plugin_generator('core_h5p'); 614 615 if ($expecteddata[1] === 'exception') { 616 $this->expectException('coding_exception'); 617 } 618 call_user_func_array([$generator, 'create_content_file'], $filedata); 619 620 $systemcontext = \context_system::instance(); 621 $filearea = $filedata[1]; 622 $filepath = '/'. dirname($filedata[0]). '/'; 623 $filename = basename($filedata[0]); 624 $itemid = $expecteddata[0]; 625 626 $fs = new \file_storage(); 627 $exists = $fs->file_exists($systemcontext->id, file_storage::COMPONENT, $filearea, $itemid, $filepath, 628 $filename); 629 if ($expecteddata[1] === true) { 630 $this->assertTrue($exists); 631 } else if ($expecteddata[1] === false) { 632 $this->assertFalse($exists); 633 } 634 } 635 636 /** 637 * Data provider for test_create_content_file(). Data from different files to be created. 638 * 639 * @return array 640 **/ 641 public function create_content_file_provider(): array { 642 return [ 643 'Create file in content with id 4' => [ 644 [ 645 'images/img1.png', 646 'content', 647 4 648 ], 649 [ 650 4, 651 true 652 ] 653 ], 654 'Create file in the editor' => [ 655 [ 656 'images/img1.png', 657 'editor' 658 ], 659 [ 660 0, 661 true 662 ] 663 ], 664 'Create file in content without id' => [ 665 [ 666 'images/img1.png', 667 'content' 668 ], 669 [ 670 0, 671 'exception' 672 ] 673 ] 674 ]; 675 } 676 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body