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_collator; 20 use Moodle\H5PCore; 21 use Moodle\H5PDisplayOptionBehaviour; 22 23 // phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod 24 25 /** 26 * 27 * Test class covering the H5PFrameworkInterface interface implementation. 28 * 29 * @package core_h5p 30 * @category test 31 * @copyright 2019 Mihail Geshoski <mihail@moodle.com> 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 * @covers \core_h5p\framework 34 * @runTestsInSeparateProcesses 35 */ 36 class framework_test extends \advanced_testcase { 37 38 /** @var \core_h5p\framework */ 39 private $framework; 40 41 /** 42 * Set up function for tests. 43 */ 44 public function setUp(): void { 45 $factory = new \core_h5p\factory(); 46 $this->framework = $factory->get_framework(); 47 } 48 49 /** 50 * Test the behaviour of getPlatformInfo(). 51 */ 52 public function test_getPlatformInfo() { 53 global $CFG; 54 55 $platforminfo = $this->framework->getPlatformInfo(); 56 57 $expected = array( 58 'name' => 'Moodle', 59 'version' => $CFG->version, 60 'h5pVersion' => $CFG->version 61 ); 62 63 $this->assertEquals($expected, $platforminfo); 64 } 65 66 /** 67 * Test the behaviour of fetchExternalData() when the store path is not defined. 68 * 69 * This test is intensive and requires downloading content of an external file, 70 * therefore it might take longer time to execute. 71 * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php. 72 */ 73 public function test_fetchExternalData_no_path_defined() { 74 75 if (!PHPUNIT_LONGTEST) { 76 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 77 } 78 79 $this->resetAfterTest(); 80 81 $library = 'H5P.Accordion'; 82 // Provide a valid URL to an external H5P content. 83 $url = $this->getExternalTestFileUrl('/'.$library.'.h5p'); 84 85 // Test fetching an external H5P content without defining a path to where the file should be stored. 86 $data = $this->framework->fetchExternalData($url, null, true); 87 88 // The response should not be empty and return true if the file was successfully downloaded. 89 $this->assertNotEmpty($data); 90 $this->assertTrue($data); 91 92 $h5pfolderpath = $this->framework->getUploadedH5pFolderPath(); 93 // The uploaded file should exist on the filesystem. 94 $this->assertTrue(file_exists($h5pfolderpath . '.h5p')); 95 } 96 97 /** 98 * Test the behaviour of fetchExternalData() when the store path is defined. 99 * 100 * This test is intensive and requires downloading content of an external file, 101 * therefore it might take longer time to execute. 102 * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php. 103 */ 104 public function test_fetchExternalData_path_defined() { 105 global $CFG; 106 107 if (!PHPUNIT_LONGTEST) { 108 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 109 } 110 111 $this->resetAfterTest(); 112 113 $library = 'H5P.Accordion'; 114 // Provide a valid URL to an external H5P content. 115 $url = $this->getExternalTestFileUrl('/'.$library.'.h5p'); 116 117 $h5pfolderpath = $CFG->tempdir . uniqid('/h5p-'); 118 119 $data = $this->framework->fetchExternalData($url, null, true, $h5pfolderpath . '.h5p'); 120 121 // The response should not be empty and return true if the content has been successfully saved to a file. 122 $this->assertNotEmpty($data); 123 $this->assertTrue($data); 124 125 // The uploaded file should exist on the filesystem. 126 $this->assertTrue(file_exists($h5pfolderpath . '.h5p')); 127 } 128 129 /** 130 * Test the behaviour of fetchExternalData() when the URL is pointing to an external file that is 131 * not an h5p content. 132 * 133 * This test is intensive and requires downloading content of an external file, 134 * therefore it might take longer time to execute. 135 * In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php. 136 */ 137 public function test_fetchExternalData_url_not_h5p() { 138 139 if (!PHPUNIT_LONGTEST) { 140 // This test is intensive and requires downloading the content of an external file. 141 $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); 142 } 143 144 $this->resetAfterTest(); 145 146 // Provide an URL to an external file that is not an H5P content file. 147 $url = $this->getExternalTestFileUrl('/h5pcontenttypes.json'); 148 149 $data = $this->framework->fetchExternalData($url, null, true); 150 151 // The response should not be empty and return true if the content has been successfully saved to a file. 152 $this->assertNotEmpty($data); 153 $this->assertTrue($data); 154 155 // The uploaded file should exist on the filesystem with it's original extension. 156 // NOTE: The file would be later validated by the H5P Validator. 157 $h5pfolderpath = $this->framework->getUploadedH5pFolderPath(); 158 $this->assertTrue(file_exists($h5pfolderpath . '.json')); 159 } 160 161 /** 162 * Test the behaviour of fetchExternalData() when the URL is invalid. 163 */ 164 public function test_fetchExternalData_url_invalid() { 165 // Provide an invalid URL to an external file. 166 $url = "someprotocol://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"; 167 168 $data = $this->framework->fetchExternalData($url, null, true); 169 170 // The response should be empty. 171 $this->assertEmpty($data); 172 } 173 174 /** 175 * Test the behaviour of setLibraryTutorialUrl(). 176 */ 177 public function test_setLibraryTutorialUrl() { 178 global $DB; 179 180 $this->resetAfterTest(); 181 182 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 183 184 // Create several libraries records. 185 $lib1 = $generator->create_library_record('Library1', 'Lib1', 1, 0, 1, '', null, 'http://tutorial1.org', 186 'http://example.org'); 187 $lib2 = $generator->create_library_record('Library2', 'Lib2', 2, 0, 1, '', null, 'http://tutorial2.org'); 188 $lib3 = $generator->create_library_record('Library3', 'Lib3', 3, 0); 189 190 // Check only lib1 tutorial URL is updated. 191 $url = 'https://newtutorial.cat'; 192 $this->framework->setLibraryTutorialUrl($lib1->machinename, $url); 193 194 $libraries = $DB->get_records('h5p_libraries'); 195 $this->assertEquals($libraries[$lib1->id]->tutorial, $url); 196 $this->assertNotEquals($libraries[$lib2->id]->tutorial, $url); 197 198 // Check lib1 tutorial URL is set to null. 199 $this->framework->setLibraryTutorialUrl($lib1->machinename, null); 200 201 $libraries = $DB->get_records('h5p_libraries'); 202 $this->assertCount(3, $libraries); 203 $this->assertNull($libraries[$lib1->id]->tutorial); 204 205 // Check no tutorial URL is set if library name doesn't exist. 206 $this->framework->setLibraryTutorialUrl('Unexisting library', $url); 207 208 $libraries = $DB->get_records('h5p_libraries'); 209 $this->assertCount(3, $libraries); 210 $this->assertNull($libraries[$lib1->id]->tutorial); 211 $this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org'); 212 $this->assertNull($libraries[$lib3->id]->tutorial); 213 214 // Check tutorial is set as expected when it was null. 215 $this->framework->setLibraryTutorialUrl($lib3->machinename, $url); 216 217 $libraries = $DB->get_records('h5p_libraries'); 218 $this->assertEquals($libraries[$lib3->id]->tutorial, $url); 219 $this->assertNull($libraries[$lib1->id]->tutorial); 220 $this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org'); 221 } 222 223 /** 224 * Test the behaviour of setErrorMessage(). 225 */ 226 public function test_setErrorMessage() { 227 // Set an error message and an error code. 228 $message = "Error message"; 229 $code = '404'; 230 231 // Set an error message. 232 $this->framework->setErrorMessage($message, $code); 233 234 // Get the error messages. 235 $errormessages = $this->framework->getMessages('error'); 236 237 $expected = new \stdClass(); 238 $expected->code = 404; 239 $expected->message = 'Error message'; 240 241 $this->assertEquals($expected, $errormessages[0]); 242 } 243 244 /** 245 * Test the behaviour of setInfoMessage(). 246 */ 247 public function test_setInfoMessage() { 248 $message = "Info message"; 249 250 // Set an info message. 251 $this->framework->setInfoMessage($message); 252 253 // Get the info messages. 254 $infomessages = $this->framework->getMessages('info'); 255 256 $expected = 'Info message'; 257 258 $this->assertEquals($expected, $infomessages[0]); 259 } 260 261 /** 262 * Test the behaviour of getMessages() when requesting the info messages. 263 */ 264 public function test_getMessages_info() { 265 // Set an info message. 266 $this->framework->setInfoMessage("Info message"); 267 // Set an error message. 268 $this->framework->setErrorMessage("Error message 1", 404); 269 270 // Get the info messages. 271 $infomessages = $this->framework->getMessages('info'); 272 273 $expected = 'Info message'; 274 275 // Make sure that only the info message has been returned. 276 $this->assertCount(1, $infomessages); 277 $this->assertEquals($expected, $infomessages[0]); 278 279 $infomessages = $this->framework->getMessages('info'); 280 281 // Make sure the info messages have now been removed. 282 $this->assertEmpty($infomessages); 283 } 284 285 /** 286 * Test the behaviour of getMessages() when requesting the error messages. 287 */ 288 public function test_getMessages_error() { 289 // Set an info message. 290 $this->framework->setInfoMessage("Info message"); 291 // Set an error message. 292 $this->framework->setErrorMessage("Error message 1", 404); 293 // Set another error message. 294 $this->framework->setErrorMessage("Error message 2", 403); 295 296 // Get the error messages. 297 $errormessages = $this->framework->getMessages('error'); 298 299 // Make sure that only the error messages are being returned. 300 $this->assertEquals(2, count($errormessages)); 301 302 $expected1 = (object) [ 303 'code' => 404, 304 'message' => 'Error message 1' 305 ]; 306 307 $expected2 = (object) [ 308 'code' => 403, 309 'message' => 'Error message 2' 310 ]; 311 312 $this->assertEquals($expected1, $errormessages[0]); 313 $this->assertEquals($expected2, $errormessages[1]); 314 315 $errormessages = $this->framework->getMessages('error'); 316 317 // Make sure the info messages have now been removed. 318 $this->assertEmpty($errormessages); 319 } 320 321 /** 322 * Test the behaviour of t() when translating existing string that does not require any arguments. 323 */ 324 public function test_t_existing_string_no_args() { 325 // Existing language string without passed arguments. 326 $translation = $this->framework->t('No copyright information available for this content.'); 327 328 // Make sure the string translation has been returned. 329 $this->assertEquals('No copyright information available for this content.', $translation); 330 } 331 332 /** 333 * Test the behaviour of t() when translating existing string that does require parameters. 334 */ 335 public function test_t_existing_string_args() { 336 // Existing language string with passed arguments. 337 $translation = $this->framework->t('Illegal option %option in %library', 338 ['%option' => 'example', '%library' => 'Test library']); 339 340 // Make sure the string translation has been returned. 341 $this->assertEquals('Illegal option example in Test library', $translation); 342 } 343 344 /** 345 * Test the behaviour of t() when translating non-existent string. 346 */ 347 public function test_t_non_existent_string() { 348 // Non-existing language string. 349 $message = 'Random message %option'; 350 351 $translation = $this->framework->t($message); 352 353 // Make sure a debugging message is triggered. 354 $this->assertDebuggingCalled("String translation cannot be found. Please add a string definition for '" . 355 $message . "' in the core_h5p component."); 356 // As the string does not exist in the mapping array, make sure the passed message is returned. 357 $this->assertEquals($message, $translation); 358 } 359 360 /** 361 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and 362 * the folder name is parsable. 363 **/ 364 public function test_getLibraryFileUrl() { 365 global $CFG; 366 367 $this->resetAfterTest(); 368 369 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 370 // Create a library record. 371 $lib = $generator->create_library_record('Library', 'Lib', 1, 1); 372 373 $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/library.json"; 374 375 // Get the URL of a file from an existing library. The provided folder name is parsable. 376 $actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json'); 377 378 // Make sure the expected URL is returned. 379 $this->assertEquals($expected, $actual); 380 } 381 382 /** 383 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a non-existent library and 384 * the folder name is parsable. 385 **/ 386 public function test_getLibraryFileUrl_non_existent_library() { 387 $this->resetAfterTest(); 388 389 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 390 // Create a library record. 391 $generator->create_library_record('Library', 'Lib', 1, 1); 392 393 // Get the URL of a file from a non-existent library. The provided folder name is parsable. 394 $actual = $this->framework->getLibraryFileUrl('Library2-1.1', 'library.json'); 395 396 // Make sure a debugging message is triggered. 397 $this->assertDebuggingCalled('The library "Library2-1.1" does not exist.'); 398 399 // Make sure that an URL is not returned. 400 $this->assertEquals(null, $actual); 401 } 402 403 /** 404 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and 405 * the folder name is not parsable. 406 **/ 407 public function test_getLibraryFileUrl_not_parsable_folder_name() { 408 $this->resetAfterTest(); 409 410 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 411 // Create a library record. 412 $generator->create_library_record('Library', 'Lib', 1, 1); 413 414 // Get the URL of a file from an existing library. The provided folder name is not parsable. 415 $actual = $this->framework->getLibraryFileUrl('Library1.1', 'library.json'); 416 417 // Make sure a debugging message is triggered. 418 $this->assertDebuggingCalled( 419 'The provided string value "Library1.1" is not a valid name for a library folder.'); 420 421 // Make sure that an URL is not returned. 422 $this->assertEquals(null, $actual); 423 } 424 425 /** 426 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple 427 * versions and the folder name is parsable. 428 **/ 429 public function test_getLibraryFileUrl_library_has_multiple_versions() { 430 global $CFG; 431 432 $this->resetAfterTest(); 433 434 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 435 // Create library records with a different minor version. 436 $lib1 = $generator->create_library_record('Library', 'Lib', 1, 1); 437 $lib2 = $generator->create_library_record('Library', 'Lib', 1, 3); 438 439 $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.3/library.json"; 440 441 // Get the URL of a file from an existing library (Library 1.3). The provided folder name is parsable. 442 $actual = $this->framework->getLibraryFileUrl('Library-1.3', 'library.json'); 443 444 // Make sure the proper URL (from the requested library version) is returned. 445 $this->assertEquals($expected, $actual); 446 } 447 448 /** 449 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple 450 * patch versions and the folder name is parsable. 451 **/ 452 public function test_getLibraryFileUrl_library_has_multiple_patch_versions() { 453 global $CFG; 454 455 $this->resetAfterTest(); 456 457 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 458 // Create library records with a different patch version. 459 $lib1 = $generator->create_library_record('Library', 'Lib', 1, 1, 2); 460 $lib2 = $generator->create_library_record('Library', 'Lib', 1, 1, 4); 461 $lib3 = $generator->create_library_record('Library', 'Lib', 1, 1, 3); 462 463 $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.1/library.json"; 464 465 // Get the URL of a file from an existing library. The provided folder name is parsable. 466 $actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json'); 467 468 // Make sure the proper URL (from the latest library patch) is returned. 469 $this->assertEquals($expected, $actual); 470 } 471 472 /** 473 * Test the behaviour of getLibraryFileUrl() when requesting a file URL from a sub-folder 474 * of an existing library and the folder name is parsable. 475 **/ 476 public function test_getLibraryFileUrl_library_subfolder() { 477 global $CFG; 478 479 $this->resetAfterTest(); 480 481 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 482 // Create a library record. 483 $lib = $generator->create_library_record('Library', 'Lib', 1, 1); 484 485 $expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/css/example.css"; 486 487 // Get the URL of a file from a sub-folder from an existing library. The provided folder name is parsable. 488 $actual = $this->framework->getLibraryFileUrl('Library-1.1/css', 'example.css'); 489 490 // Make sure the proper URL is returned. 491 $this->assertEquals($expected, $actual); 492 } 493 494 /** 495 * Test the behaviour of loadAddons(). 496 */ 497 public function test_loadAddons() { 498 $this->resetAfterTest(); 499 500 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 501 502 // Create a Library addon (1.1). 503 $generator->create_library_record('Library', 'Lib', 1, 1, 2, 504 '', '/regex1/'); 505 // Create a Library addon (1.3). 506 $generator->create_library_record('Library', 'Lib', 1, 3, 2, 507 '', '/regex2/'); 508 // Create a Library addon (1.2). 509 $generator->create_library_record('Library', 'Lib', 1, 2, 2, 510 '', '/regex3/'); 511 // Create a Library1 addon (1.2) 512 $generator->create_library_record('Library1', 'Lib1', 1, 2, 2, 513 '', '/regex11/'); 514 515 // Load the latest version of each addon. 516 $addons = $this->framework->loadAddons(); 517 518 // The addons array should return 2 results (Library and Library1 addon). 519 $this->assertCount(2, $addons); 520 521 // Ensure the addons array is consistently ordered before asserting their contents. 522 core_collator::asort_array_of_arrays_by_key($addons, 'machineName'); 523 [$addonone, $addontwo] = array_values($addons); 524 525 // Make sure the version 1.3 is the latest 'Library' addon version. 526 $this->assertEquals('Library', $addonone['machineName']); 527 $this->assertEquals(1, $addonone['majorVersion']); 528 $this->assertEquals(3, $addonone['minorVersion']); 529 530 // Make sure the version 1.2 is the latest 'Library1' addon version. 531 $this->assertEquals('Library1', $addontwo['machineName']); 532 $this->assertEquals(1, $addontwo['majorVersion']); 533 $this->assertEquals(2, $addontwo['minorVersion']); 534 } 535 536 /** 537 * Test the behaviour of loadLibraries(). 538 */ 539 public function test_loadLibraries() { 540 $this->resetAfterTest(); 541 542 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 543 544 // Generate h5p related data. 545 $generator->generate_h5p_data(); 546 547 // Load all libraries. 548 $libraries = $this->framework->loadLibraries(); 549 550 // Make sure all libraries are returned. 551 $this->assertNotEmpty($libraries); 552 $this->assertCount(6, $libraries); 553 $this->assertEquals('MainLibrary', $libraries['MainLibrary'][0]->machine_name); 554 $this->assertEquals('1', $libraries['MainLibrary'][0]->major_version); 555 $this->assertEquals('0', $libraries['MainLibrary'][0]->minor_version); 556 $this->assertEquals('1', $libraries['MainLibrary'][0]->patch_version); 557 } 558 559 /** 560 * Test the behaviour of test_getLibraryId() when requesting an existing machine name. 561 */ 562 public function test_getLibraryId_existing_machine_name() { 563 $this->resetAfterTest(); 564 565 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 566 567 // Create a library. 568 $lib = $generator->create_library_record('Library', 'Lib', 1, 1, 2); 569 570 // Request the library ID of the library with machine name 'Library'. 571 $libraryid = $this->framework->getLibraryId('Library'); 572 573 // Make sure the library ID is being returned. 574 $this->assertNotFalse($libraryid); 575 $this->assertEquals($lib->id, $libraryid); 576 } 577 578 /** 579 * Test the behaviour of test_getLibraryId() when requesting a non-existent machine name. 580 */ 581 public function test_getLibraryId_non_existent_machine_name() { 582 $this->resetAfterTest(); 583 584 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 585 586 // Create a library. 587 $generator->create_library_record('Library', 'Lib', 1, 1, 2); 588 589 // Request the library ID of the library with machinename => 'TestLibrary' (non-existent). 590 $libraryid = $this->framework->getLibraryId('TestLibrary'); 591 592 // Make sure the library ID not being returned. 593 $this->assertFalse($libraryid); 594 } 595 596 /** 597 * Test the behaviour of test_getLibraryId() when requesting a non-existent major version. 598 */ 599 public function test_getLibraryId_non_existent_major_version() { 600 $this->resetAfterTest(); 601 602 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 603 604 // Create a library. 605 $generator->create_library_record('Library', 'Lib', 1, 1, 2); 606 607 // Request the library ID of the library with machine name => 'Library', majorversion => 2 (non-existent). 608 $libraryid = $this->framework->getLibraryId('Library', 2); 609 610 // Make sure the library ID not being returned. 611 $this->assertFalse($libraryid); 612 } 613 614 /** 615 * Test the behaviour of test_getLibraryId() when requesting a non-existent minor version. 616 */ 617 public function test_getLibraryId_non_existent_minor_version() { 618 $this->resetAfterTest(); 619 620 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 621 622 // Create a library. 623 $generator->create_library_record('Library', 'Lib', 1, 1, 2); 624 625 // Request the library ID of the library with machine name => 'Library', 626 // majorversion => 1, minorversion => 2 (non-existent). 627 $libraryid = $this->framework->getLibraryId('Library', 1, 2); 628 629 // Make sure the library ID not being returned. 630 $this->assertFalse($libraryid); 631 } 632 633 /** 634 * Test the behaviour of isPatchedLibrary(). 635 * 636 * @dataProvider isPatchedLibrary_provider 637 * @param array $libraryrecords Array containing data for the library creation 638 * @param array $testlibrary Array containing the test library data 639 * @param bool $expected The expectation whether the library is patched or not 640 **/ 641 public function test_isPatchedLibrary(array $libraryrecords, array $testlibrary, bool $expected): void { 642 $this->resetAfterTest(); 643 644 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 645 646 foreach ($libraryrecords as $library) { 647 call_user_func_array([$generator, 'create_library_record'], $library); 648 } 649 650 $this->assertEquals($expected, $this->framework->isPatchedLibrary($testlibrary)); 651 } 652 653 /** 654 * Data provider for test_isPatchedLibrary(). 655 * 656 * @return array 657 */ 658 public function isPatchedLibrary_provider(): array { 659 return [ 660 'Unpatched library. No different versioning' => [ 661 [ 662 ['TestLibrary', 'Test', 1, 1, 2], 663 ], 664 [ 665 'machineName' => 'TestLibrary', 666 'majorVersion' => 1, 667 'minorVersion' => 1, 668 'patchVersion' => 2 669 ], 670 false, 671 ], 672 'Major version identical; Minor version identical; Patch version newer' => [ 673 [ 674 ['TestLibrary', 'Test', 1, 1, 2], 675 ], 676 [ 677 'machineName' => 'TestLibrary', 678 'majorVersion' => 1, 679 'minorVersion' => 1, 680 'patchVersion' => 3 681 ], 682 true, 683 ], 684 'Major version identical; Minor version newer; Patch version newer' => [ 685 [ 686 ['TestLibrary', 'Test', 1, 1, 2], 687 ], 688 [ 689 'machineName' => 'TestLibrary', 690 'majorVersion' => 1, 691 'minorVersion' => 2, 692 'patchVersion' => 3 693 ], 694 false, 695 ], 696 'Major version identical; Minor version identical; Patch version older' => [ 697 [ 698 ['TestLibrary', 'Test', 1, 1, 2], 699 ], 700 [ 701 'machineName' => 'TestLibrary', 702 'majorVersion' => 1, 703 'minorVersion' => 1, 704 'patchVersion' => 1 705 ], 706 false, 707 ], 708 'Major version identical; Minor version newer; Patch version older' => [ 709 [ 710 ['TestLibrary', 'Test', 1, 1, 2], 711 ], 712 [ 713 'machineName' => 'TestLibrary', 714 'majorVersion' => 1, 715 'minorVersion' => 2, 716 'patchVersion' => 1 717 ], 718 false, 719 ], 720 'Major version newer; Minor version identical; Patch version older' => [ 721 [ 722 ['TestLibrary', 'Test', 1, 1, 2], 723 ], 724 [ 725 'machineName' => 'TestLibrary', 726 'majorVersion' => 2, 727 'minorVersion' => 1, 728 'patchVersion' => 1 729 ], 730 false, 731 ], 732 'Major version newer; Minor version identical; Patch version newer' => [ 733 [ 734 ['TestLibrary', 'Test', 1, 1, 2], 735 ], 736 [ 737 'machineName' => 'TestLibrary', 738 'majorVersion' => 2, 739 'minorVersion' => 1, 740 'patchVersion' => 3 741 ], 742 false, 743 ], 744 745 'Major version older; Minor version identical; Patch version older' => [ 746 [ 747 ['TestLibrary', 'Test', 1, 1, 2], 748 ], 749 [ 750 'machineName' => 'TestLibrary', 751 'majorVersion' => 0, 752 'minorVersion' => 1, 753 'patchVersion' => 1 754 ], 755 false, 756 ], 757 'Major version older; Minor version identical; Patch version newer' => [ 758 [ 759 ['TestLibrary', 'Test', 1, 1, 2], 760 ], 761 [ 762 'machineName' => 'TestLibrary', 763 'majorVersion' => 0, 764 'minorVersion' => 1, 765 'patchVersion' => 3 766 ], 767 false, 768 ], 769 ]; 770 } 771 772 /** 773 * Test the behaviour of isInDevMode(). 774 */ 775 public function test_isInDevMode() { 776 $isdevmode = $this->framework->isInDevMode(); 777 778 $this->assertFalse($isdevmode); 779 } 780 781 /** 782 * Test the behaviour of mayUpdateLibraries(). 783 */ 784 public function test_mayUpdateLibraries(): void { 785 global $DB; 786 787 $this->resetAfterTest(); 788 789 // Create some users. 790 $contextsys = \context_system::instance(); 791 $user = $this->getDataGenerator()->create_user(); 792 $admin = get_admin(); 793 $managerrole = $DB->get_record('role', ['shortname' => 'manager'], '*', MUST_EXIST); 794 $studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST); 795 $manager = $this->getDataGenerator()->create_user(); 796 role_assign($managerrole->id, $manager->id, $contextsys); 797 798 // Create a course with a label and enrol the user. 799 $course = $this->getDataGenerator()->create_course(); 800 $label = $this->getDataGenerator()->create_module('label', ['course' => $course->id]); 801 list(, $labelcm) = get_course_and_cm_from_instance($label->id, 'label'); 802 $contextlabel = \context_module::instance($labelcm->id); 803 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student'); 804 805 // Create the .h5p file. 806 $path = __DIR__ . '/fixtures/h5ptest.zip'; 807 808 // Admin and manager should have permission to update libraries. 809 $file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextsys); 810 $this->framework->set_file($file); 811 $mayupdatelib = $this->framework->mayUpdateLibraries(); 812 $this->assertTrue($mayupdatelib); 813 814 $file = helper::create_fake_stored_file_from_path($path, $manager->id, $contextsys); 815 $this->framework->set_file($file); 816 $mayupdatelib = $this->framework->mayUpdateLibraries(); 817 $this->assertTrue($mayupdatelib); 818 819 // By default, normal user hasn't permission to update libraries (in both contexts, system and module label). 820 $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys); 821 $this->framework->set_file($file); 822 $mayupdatelib = $this->framework->mayUpdateLibraries(); 823 $this->assertFalse($mayupdatelib); 824 825 $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel); 826 $this->framework->set_file($file); 827 $mayupdatelib = $this->framework->mayUpdateLibraries(); 828 $this->assertFalse($mayupdatelib); 829 830 // If the current user (admin) can update libraries, the method should return true (even if the file userid hasn't the 831 // required capabilility in the file context). 832 $file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextlabel); 833 $this->framework->set_file($file); 834 $mayupdatelib = $this->framework->mayUpdateLibraries(); 835 $this->assertTrue($mayupdatelib); 836 837 // If the update capability is assigned to the user, they should be able to update the libraries (only in the context 838 // where the capability has been assigned). 839 $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel); 840 $this->framework->set_file($file); 841 $mayupdatelib = $this->framework->mayUpdateLibraries(); 842 $this->assertFalse($mayupdatelib); 843 assign_capability('moodle/h5p:updatelibraries', CAP_ALLOW, $studentrole->id, $contextlabel); 844 $mayupdatelib = $this->framework->mayUpdateLibraries(); 845 $this->assertTrue($mayupdatelib); 846 $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys); 847 $this->framework->set_file($file); 848 $mayupdatelib = $this->framework->mayUpdateLibraries(); 849 $this->assertFalse($mayupdatelib); 850 } 851 852 /** 853 * Test the behaviour of get_file() and set_file(). 854 */ 855 public function test_get_file(): void { 856 $this->resetAfterTest(); 857 858 // Create some users. 859 $contextsys = \context_system::instance(); 860 $user = $this->getDataGenerator()->create_user(); 861 862 // The H5P file. 863 $path = __DIR__ . '/fixtures/h5ptest.zip'; 864 865 // An error should be raised when it's called before initialitzing it. 866 $this->expectException('coding_exception'); 867 $this->expectExceptionMessage('Using get_file() before file is set'); 868 $this->framework->get_file(); 869 870 // Check the value when only path and user are set. 871 $file = helper::create_fake_stored_file_from_path($path, $user->id); 872 $this->framework->set_file($file); 873 $file = $this->framework->get_file(); 874 $this->assertEquals($user->id, $$file->get_userid()); 875 $this->assertEquals($contextsys->id, $file->get_contextid()); 876 877 // Check the value when also the context is set. 878 $course = $this->getDataGenerator()->create_course(); 879 $contextcourse = \context_course::instance($course->id); 880 $file = helper::create_fake_stored_file_from_path($path, $user->id, $contextcourse); 881 $this->framework->set_file($file); 882 $file = $this->framework->get_file(); 883 $this->assertEquals($user->id, $$file->get_userid()); 884 $this->assertEquals($contextcourse->id, $file->get_contextid()); 885 } 886 887 /** 888 * Test the behaviour of saveLibraryData() when saving data for a new library. 889 */ 890 public function test_saveLibraryData_new_library() { 891 global $DB; 892 893 $this->resetAfterTest(); 894 895 $librarydata = array( 896 'title' => 'Test', 897 'machineName' => 'TestLibrary', 898 'majorVersion' => '1', 899 'minorVersion' => '0', 900 'patchVersion' => '2', 901 'runnable' => 1, 902 'fullscreen' => 1, 903 'preloadedJs' => array( 904 array( 905 'path' => 'js/name.min.js' 906 ) 907 ), 908 'preloadedCss' => array( 909 array( 910 'path' => 'css/name.css' 911 ) 912 ), 913 'dropLibraryCss' => array( 914 array( 915 'machineName' => 'Name2' 916 ) 917 ) 918 ); 919 920 // Create a new library. 921 $this->framework->saveLibraryData($librarydata); 922 923 $library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]); 924 925 // Make sure the library data was properly saved. 926 $this->assertNotEmpty($library); 927 $this->assertNotEmpty($librarydata['libraryId']); 928 $this->assertEquals($librarydata['title'], $library->title); 929 $this->assertEquals($librarydata['machineName'], $library->machinename); 930 $this->assertEquals($librarydata['majorVersion'], $library->majorversion); 931 $this->assertEquals($librarydata['minorVersion'], $library->minorversion); 932 $this->assertEquals($librarydata['patchVersion'], $library->patchversion); 933 $this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs); 934 $this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss); 935 $this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss); 936 } 937 938 /** 939 * Test the behaviour of saveLibraryData() when saving (updating) data for an existing library. 940 */ 941 public function test_saveLibraryData_existing_library() { 942 global $DB; 943 944 $this->resetAfterTest(); 945 946 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 947 948 // Create a library record. 949 $library = $generator->create_library_record('TestLibrary', 'Test', 1, 0, 2); 950 951 $librarydata = array( 952 'libraryId' => $library->id, 953 'title' => 'Test1', 954 'machineName' => 'TestLibrary', 955 'majorVersion' => '1', 956 'minorVersion' => '2', 957 'patchVersion' => '2', 958 'runnable' => 1, 959 'fullscreen' => 1, 960 'preloadedJs' => array( 961 array( 962 'path' => 'js/name.min.js' 963 ) 964 ), 965 'preloadedCss' => array( 966 array( 967 'path' => 'css/name.css' 968 ) 969 ), 970 'dropLibraryCss' => array( 971 array( 972 'machineName' => 'Name2' 973 ) 974 ) 975 ); 976 977 // Update the library. 978 $this->framework->saveLibraryData($librarydata, false); 979 980 $library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]); 981 982 // Make sure the library data was properly updated. 983 $this->assertNotEmpty($library); 984 $this->assertNotEmpty($librarydata['libraryId']); 985 $this->assertEquals($librarydata['title'], $library->title); 986 $this->assertEquals($librarydata['machineName'], $library->machinename); 987 $this->assertEquals($librarydata['majorVersion'], $library->majorversion); 988 $this->assertEquals($librarydata['minorVersion'], $library->minorversion); 989 $this->assertEquals($librarydata['patchVersion'], $library->patchversion); 990 $this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs); 991 $this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss); 992 $this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss); 993 } 994 995 /** 996 * Test the behaviour of insertContent(). 997 */ 998 public function test_insertContent() { 999 global $DB; 1000 1001 $this->resetAfterTest(); 1002 1003 $content = array( 1004 'params' => json_encode(['param1' => 'Test']), 1005 'library' => array( 1006 'libraryId' => 1 1007 ), 1008 'disable' => 8 1009 ); 1010 1011 // Insert h5p content. 1012 $contentid = $this->framework->insertContent($content); 1013 1014 // Get the entered content from the db. 1015 $dbcontent = $DB->get_record('h5p', ['id' => $contentid]); 1016 1017 // Make sure the h5p content was properly inserted. 1018 $this->assertNotEmpty($dbcontent); 1019 $this->assertEquals($content['params'], $dbcontent->jsoncontent); 1020 $this->assertEquals($content['library']['libraryId'], $dbcontent->mainlibraryid); 1021 $this->assertEquals($content['disable'], $dbcontent->displayoptions); 1022 } 1023 1024 /** 1025 * Test the behaviour of insertContent(). 1026 */ 1027 public function test_insertContent_latestlibrary() { 1028 global $DB; 1029 1030 $this->resetAfterTest(); 1031 1032 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1033 // Create a library record. 1034 $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2); 1035 1036 $content = array( 1037 'params' => json_encode(['param1' => 'Test']), 1038 'library' => array( 1039 'libraryId' => 0, 1040 'machineName' => 'TestLibrary', 1041 ), 1042 'disable' => 8 1043 ); 1044 1045 // Insert h5p content. 1046 $contentid = $this->framework->insertContent($content); 1047 1048 // Get the entered content from the db. 1049 $dbcontent = $DB->get_record('h5p', ['id' => $contentid]); 1050 1051 // Make sure the h5p content was properly inserted. 1052 $this->assertNotEmpty($dbcontent); 1053 $this->assertEquals($content['params'], $dbcontent->jsoncontent); 1054 $this->assertEquals($content['disable'], $dbcontent->displayoptions); 1055 // As the libraryId was empty, the latest library has been used. 1056 $this->assertEquals($lib->id, $dbcontent->mainlibraryid); 1057 } 1058 1059 /** 1060 * Test the behaviour of updateContent(). 1061 */ 1062 public function test_updateContent() { 1063 global $DB; 1064 1065 $this->resetAfterTest(); 1066 1067 /** @var \core_h5p_generator $generator */ 1068 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1069 1070 // Create a library record. 1071 $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2); 1072 1073 // Create an h5p content with 'TestLibrary' as it's main library. 1074 $contentid = $generator->create_h5p_record($lib->id); 1075 1076 $content = array( 1077 'id' => $contentid, 1078 'params' => json_encode(['param2' => 'Test2']), 1079 'library' => array( 1080 'libraryId' => $lib->id 1081 ), 1082 'disable' => 8 1083 ); 1084 1085 // Update the h5p content. 1086 $this->framework->updateContent($content); 1087 1088 $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]); 1089 1090 // Make sure the h5p content was properly updated. 1091 $this->assertNotEmpty($h5pcontent); 1092 $this->assertNotEmpty($h5pcontent->pathnamehash); 1093 $this->assertNotEmpty($h5pcontent->contenthash); 1094 $this->assertEquals($content['params'], $h5pcontent->jsoncontent); 1095 $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid); 1096 $this->assertEquals($content['disable'], $h5pcontent->displayoptions); 1097 } 1098 1099 /** 1100 * Test the behaviour of updateContent() with metadata. 1101 * 1102 * @covers ::updateContent 1103 */ 1104 public function test_updateContent_withmetadata(): void { 1105 global $DB; 1106 1107 $this->resetAfterTest(); 1108 1109 /** @var \core_h5p_generator $generator */ 1110 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1111 1112 // Create a library record. 1113 $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2); 1114 1115 // Create an h5p content with 'TestLibrary' as it's main library. 1116 $contentid = $generator->create_h5p_record($lib->id); 1117 1118 $params = ['param2' => 'Test2']; 1119 $metadata = [ 1120 'license' => 'CC BY', 1121 'licenseVersion' => '4.0', 1122 'yearFrom' => 2000, 1123 'yearTo' => 2023, 1124 'defaultLanguage' => 'ca', 1125 ]; 1126 $content = [ 1127 'id' => $contentid, 1128 'params' => json_encode($params), 1129 'library' => [ 1130 'libraryId' => $lib->id, 1131 ], 1132 'disable' => 8, 1133 'metadata' => $metadata, 1134 ]; 1135 1136 // Update the h5p content. 1137 $this->framework->updateContent($content); 1138 1139 $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]); 1140 1141 // Make sure the h5p content was properly updated. 1142 $this->assertNotEmpty($h5pcontent); 1143 $this->assertNotEmpty($h5pcontent->pathnamehash); 1144 $this->assertNotEmpty($h5pcontent->contenthash); 1145 $this->assertEquals(json_encode(array_merge($params, ['metadata' => $metadata])), $h5pcontent->jsoncontent); 1146 $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid); 1147 $this->assertEquals($content['disable'], $h5pcontent->displayoptions); 1148 } 1149 1150 /** 1151 * Test the behaviour of saveLibraryDependencies(). 1152 */ 1153 public function test_saveLibraryDependencies() { 1154 global $DB; 1155 1156 $this->resetAfterTest(); 1157 1158 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1159 1160 // Create a library 'Library'. 1161 $library = $generator->create_library_record('Library', 'Title'); 1162 // Create a library 'DependencyLibrary1'. 1163 $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1'); 1164 // Create a library 'DependencyLibrary2'. 1165 $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2'); 1166 1167 $dependencies = array( 1168 array( 1169 'machineName' => $dependency1->machinename, 1170 'majorVersion' => $dependency1->majorversion, 1171 'minorVersion' => $dependency1->minorversion 1172 ), 1173 array( 1174 'machineName' => $dependency2->machinename, 1175 'majorVersion' => $dependency2->majorversion, 1176 'minorVersion' => $dependency2->minorversion 1177 ), 1178 ); 1179 1180 // Set 'DependencyLibrary1' and 'DependencyLibrary2' as library dependencies of 'Library'. 1181 $this->framework->saveLibraryDependencies($library->id, $dependencies, 'preloaded'); 1182 1183 $libdependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library->id], 'id ASC'); 1184 1185 // Make sure the library dependencies for 'Library' are properly set. 1186 $this->assertEquals(2, count($libdependencies)); 1187 $this->assertEquals($dependency1->id, reset($libdependencies)->requiredlibraryid); 1188 $this->assertEquals($dependency2->id, end($libdependencies)->requiredlibraryid); 1189 } 1190 1191 /** 1192 * Test the behaviour of deleteContentData(). 1193 */ 1194 public function test_deleteContentData() { 1195 global $DB; 1196 1197 $this->resetAfterTest(); 1198 1199 /** @var \core_h5p_generator $generator */ 1200 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1201 // For the mod_h5pactivity component, the activity needs to be created too. 1202 $course = $this->getDataGenerator()->create_course(); 1203 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 1204 $this->setUser($user); 1205 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 1206 $activitycontext = \context_module::instance($activity->cmid); 1207 $filerecord = [ 1208 'contextid' => $activitycontext->id, 1209 'component' => 'mod_h5pactivity', 1210 'filearea' => 'package', 1211 'itemid' => 0, 1212 'filepath' => '/', 1213 'filename' => 'dummy.h5p', 1214 'addxapistate' => true, 1215 ]; 1216 1217 // Generate some h5p related data. 1218 $data = $generator->generate_h5p_data(false, $filerecord); 1219 $h5pid = $data->h5pcontent->h5pid; 1220 1221 // Make sure the particular h5p content exists in the DB. 1222 $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid])); 1223 // Make sure the content libraries exists in the DB. 1224 $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid])); 1225 // Make sure the particular xAPI state exists in the DB. 1226 $records = $DB->get_records('xapi_states'); 1227 $record = reset($records); 1228 $this->assertCount(1, $records); 1229 $this->assertNotNull($record->statedata); 1230 1231 // Delete the h5p content and it's related data. 1232 $this->framework->deleteContentData($h5pid); 1233 1234 // The particular h5p content should no longer exist in the db. 1235 $this->assertEmpty($DB->get_record('h5p', ['id' => $h5pid])); 1236 // The particular content libraries should no longer exist in the db. 1237 $this->assertEmpty($DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid])); 1238 // The xAPI state should be reseted. 1239 $records = $DB->get_records('xapi_states'); 1240 $record = reset($records); 1241 $this->assertCount(1, $records); 1242 $this->assertNull($record->statedata); 1243 } 1244 1245 /** 1246 * Test the behaviour of resetContentUserData(). 1247 */ 1248 public function test_resetContentUserData() { 1249 global $DB; 1250 1251 $this->resetAfterTest(); 1252 1253 /** @var \core_h5p_generator $generator */ 1254 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1255 // For the mod_h5pactivity component, the activity needs to be created too. 1256 $course = $this->getDataGenerator()->create_course(); 1257 $user = $this->getDataGenerator()->create_and_enrol($course, 'student'); 1258 $this->setUser($user); 1259 $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]); 1260 $activitycontext = \context_module::instance($activity->cmid); 1261 $filerecord = [ 1262 'contextid' => $activitycontext->id, 1263 'component' => 'mod_h5pactivity', 1264 'filearea' => 'package', 1265 'itemid' => 0, 1266 'filepath' => '/', 1267 'filename' => 'dummy.h5p', 1268 'addxapistate' => true, 1269 ]; 1270 1271 // Generate some h5p related data. 1272 $data = $generator->generate_h5p_data(false, $filerecord); 1273 $h5pid = $data->h5pcontent->h5pid; 1274 1275 // Make sure the H5P content, libraries and xAPI state exist in the DB. 1276 $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid])); 1277 $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid])); 1278 $records = $DB->get_records('xapi_states'); 1279 $record = reset($records); 1280 $this->assertCount(1, $records); 1281 $this->assertNotNull($record->statedata); 1282 1283 // Reset the user data associated to this H5P content. 1284 $this->framework->resetContentUserData($h5pid); 1285 1286 // The H5P content should still exist in the db. 1287 $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid])); 1288 // The particular content libraries should still exist in the db. 1289 $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid])); 1290 // The xAPI state should still exist in the db, but should be reset. 1291 $records = $DB->get_records('xapi_states'); 1292 $record = reset($records); 1293 $this->assertCount(1, $records); 1294 $this->assertNull($record->statedata); 1295 } 1296 1297 /** 1298 * Test the behaviour of deleteLibraryUsage(). 1299 */ 1300 public function test_deleteLibraryUsage() { 1301 global $DB; 1302 1303 $this->resetAfterTest(); 1304 1305 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1306 1307 // Generate some h5p related data. 1308 $data = $generator->generate_h5p_data(); 1309 $h5pid = $data->h5pcontent->h5pid; 1310 1311 // Get the h5p content libraries from the DB. 1312 $h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]); 1313 1314 // The particular h5p content should have 5 content libraries. 1315 $this->assertNotEmpty($h5pcontentlibraries); 1316 $this->assertCount(5, $h5pcontentlibraries); 1317 1318 // Delete the h5p content and it's related data. 1319 $this->framework->deleteLibraryUsage($h5pid); 1320 1321 // Get the h5p content libraries from the DB. 1322 $h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]); 1323 1324 // The particular h5p content libraries should no longer exist in the db. 1325 $this->assertEmpty($h5pcontentlibraries); 1326 } 1327 1328 /** 1329 * Test the behaviour of test_saveLibraryUsage(). 1330 */ 1331 public function test_saveLibraryUsage() { 1332 global $DB; 1333 1334 $this->resetAfterTest(); 1335 1336 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1337 1338 // Create a library 'Library'. 1339 $library = $generator->create_library_record('Library', 'Title'); 1340 // Create a library 'DependencyLibrary1'. 1341 $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1'); 1342 // Create a library 'DependencyLibrary2'. 1343 $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2'); 1344 // Create an h5p content with 'Library' as it's main library. 1345 $contentid = $generator->create_h5p_record($library->id); 1346 1347 $dependencies = array( 1348 array( 1349 'library' => array( 1350 'libraryId' => $dependency1->id, 1351 'machineName' => $dependency1->machinename, 1352 'dropLibraryCss' => $dependency1->droplibrarycss 1353 ), 1354 'type' => 'preloaded', 1355 'weight' => 1 1356 ), 1357 array( 1358 'library' => array( 1359 'libraryId' => $dependency2->id, 1360 'machineName' => $dependency2->machinename, 1361 'dropLibraryCss' => $dependency2->droplibrarycss 1362 ), 1363 'type' => 'preloaded', 1364 'weight' => 2 1365 ), 1366 ); 1367 1368 // Save 'DependencyLibrary1' and 'DependencyLibrary2' as h5p content libraries. 1369 $this->framework->saveLibraryUsage($contentid, $dependencies); 1370 1371 // Get the h5p content libraries from the DB. 1372 $libdependencies = $DB->get_records('h5p_contents_libraries', ['h5pid' => $contentid], 'id ASC'); 1373 1374 // Make sure that 'DependencyLibrary1' and 'DependencyLibrary2' are properly set as h5p content libraries. 1375 $this->assertEquals(2, count($libdependencies)); 1376 $this->assertEquals($dependency1->id, reset($libdependencies)->libraryid); 1377 $this->assertEquals($dependency2->id, end($libdependencies)->libraryid); 1378 } 1379 1380 /** 1381 * Test the behaviour of getLibraryUsage() without skipping a particular h5p content. 1382 */ 1383 public function test_getLibraryUsage_no_skip_content() { 1384 $this->resetAfterTest(); 1385 1386 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1387 1388 // Generate h5p related data. 1389 $generateddata = $generator->generate_h5p_data(); 1390 // The Id of the library 'Library1'. 1391 $library1id = $generateddata->lib1->data->id; 1392 // The Id of the library 'Library2'. 1393 $library2id = $generateddata->lib2->data->id; 1394 // The Id of the library 'Library5'. 1395 $library5id = $generateddata->lib5->data->id; 1396 1397 // Get the library usage for 'Library1' (do not skip content). 1398 $data = $this->framework->getLibraryUsage($library1id); 1399 1400 $expected = array( 1401 'content' => 1, 1402 'libraries' => 1 1403 ); 1404 1405 // Make sure 'Library1' is used by 1 content and is a dependency to 1 library. 1406 $this->assertEquals($expected, $data); 1407 1408 // Get the library usage for 'Library2' (do not skip content). 1409 $data = $this->framework->getLibraryUsage($library2id); 1410 1411 $expected = array( 1412 'content' => 1, 1413 'libraries' => 2, 1414 ); 1415 1416 // Make sure 'Library2' is used by 1 content and is a dependency to 2 libraries. 1417 $this->assertEquals($expected, $data); 1418 1419 // Get the library usage for 'Library5' (do not skip content). 1420 $data = $this->framework->getLibraryUsage($library5id); 1421 1422 $expected = array( 1423 'content' => 0, 1424 'libraries' => 1, 1425 ); 1426 1427 // Make sure 'Library5' is not used by any content and is a dependency to 1 library. 1428 $this->assertEquals($expected, $data); 1429 } 1430 1431 /** 1432 * Test the behaviour of getLibraryUsage() when skipping a particular content. 1433 */ 1434 public function test_getLibraryUsage_skip_content() { 1435 $this->resetAfterTest(); 1436 1437 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1438 1439 // Generate h5p related data. 1440 $generateddata = $generator->generate_h5p_data(); 1441 // The Id of the library 'Library1'. 1442 $library1id = $generateddata->lib1->data->id; 1443 1444 // Get the library usage for 'Library1' (skip content). 1445 $data = $this->framework->getLibraryUsage($library1id, true); 1446 $expected = array( 1447 'content' => -1, 1448 'libraries' => 1, 1449 ); 1450 1451 // Make sure 'Library1' is a dependency to 1 library. 1452 $this->assertEquals($expected, $data); 1453 } 1454 1455 /** 1456 * Test the behaviour of loadLibrary() when requesting an existing library. 1457 */ 1458 public function test_loadLibrary_existing_library() { 1459 $this->resetAfterTest(); 1460 1461 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1462 1463 // Generate h5p related data. 1464 $generateddata = $generator->generate_h5p_data(); 1465 // The library data of 'Library1'. 1466 $library1 = $generateddata->lib1->data; 1467 // The library data of 'Library5'. 1468 $library5 = $generateddata->lib5->data; 1469 1470 // The preloaded dependencies. 1471 $preloadeddependencies = array(); 1472 1473 foreach ($generateddata->lib1->dependencies as $preloadeddependency) { 1474 $preloadeddependencies[] = array( 1475 'machineName' => $preloadeddependency->machinename, 1476 'majorVersion' => $preloadeddependency->majorversion, 1477 'minorVersion' => $preloadeddependency->minorversion 1478 ); 1479 } 1480 1481 // Create a dynamic dependency. 1482 $generator->create_library_dependency_record($library1->id, $library5->id, 'dynamic'); 1483 1484 $dynamicdependencies[] = array( 1485 'machineName' => $library5->machinename, 1486 'majorVersion' => $library5->majorversion, 1487 'minorVersion' => $library5->minorversion 1488 ); 1489 1490 // Load 'Library1' data. 1491 $data = $this->framework->loadLibrary($library1->machinename, $library1->majorversion, 1492 $library1->minorversion); 1493 1494 $expected = array( 1495 'libraryId' => $library1->id, 1496 'title' => $library1->title, 1497 'machineName' => $library1->machinename, 1498 'majorVersion' => $library1->majorversion, 1499 'minorVersion' => $library1->minorversion, 1500 'patchVersion' => $library1->patchversion, 1501 'runnable' => $library1->runnable, 1502 'fullscreen' => $library1->fullscreen, 1503 'embedTypes' => $library1->embedtypes, 1504 'preloadedJs' => $library1->preloadedjs, 1505 'preloadedCss' => $library1->preloadedcss, 1506 'dropLibraryCss' => $library1->droplibrarycss, 1507 'semantics' => $library1->semantics, 1508 'preloadedDependencies' => $preloadeddependencies, 1509 'dynamicDependencies' => $dynamicdependencies 1510 ); 1511 1512 // Make sure the 'Library1' data is properly loaded. 1513 $this->assertEquals($expected, $data); 1514 } 1515 1516 /** 1517 * Test the behaviour of loadLibrary() when requesting a non-existent library. 1518 */ 1519 public function test_loadLibrary_non_existent_library() { 1520 $this->resetAfterTest(); 1521 1522 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1523 1524 // Generate h5p related data. 1525 $generator->generate_h5p_data(); 1526 1527 // Attempt to load a non-existent library. 1528 $data = $this->framework->loadLibrary('MissingLibrary', 1, 2); 1529 1530 // Make sure nothing is loaded. 1531 $this->assertFalse($data); 1532 } 1533 1534 /** 1535 * Test the behaviour of loadLibrarySemantics(). 1536 * 1537 * @dataProvider loadLibrarySemantics_provider 1538 * @param array $libraryrecords Array containing data for the library creation 1539 * @param array $testlibrary Array containing the test library data 1540 * @param string $expected The expected semantics value 1541 **/ 1542 public function test_loadLibrarySemantics(array $libraryrecords, array $testlibrary, string $expected): void { 1543 $this->resetAfterTest(); 1544 1545 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1546 1547 foreach ($libraryrecords as $library) { 1548 call_user_func_array([$generator, 'create_library_record'], $library); 1549 } 1550 1551 $this->assertEquals($expected, $this->framework->loadLibrarySemantics( 1552 $testlibrary['machinename'], $testlibrary['majorversion'], $testlibrary['minorversion'])); 1553 } 1554 1555 /** 1556 * Data provider for test_loadLibrarySemantics(). 1557 * 1558 * @return array 1559 */ 1560 public function loadLibrarySemantics_provider(): array { 1561 1562 $semantics = json_encode( 1563 [ 1564 'type' => 'text', 1565 'name' => 'text', 1566 'label' => 'Plain text', 1567 'description' => 'Please add some text' 1568 ] 1569 ); 1570 1571 return [ 1572 'Library with semantics' => [ 1573 [ 1574 ['Library1', 'Lib1', 1, 1, 2, $semantics], 1575 ], 1576 [ 1577 'machinename' => 'Library1', 1578 'majorversion' => 1, 1579 'minorversion' => 1 1580 ], 1581 $semantics, 1582 ], 1583 'Library without semantics' => [ 1584 [ 1585 ['Library2', 'Lib2', 1, 2, 2, ''], 1586 ], 1587 [ 1588 'machinename' => 'Library2', 1589 'majorversion' => 1, 1590 'minorversion' => 2 1591 ], 1592 '', 1593 ] 1594 ]; 1595 } 1596 1597 /** 1598 * Test the behaviour of alterLibrarySemantics(). 1599 */ 1600 public function test_alterLibrarySemantics() { 1601 global $DB; 1602 1603 $this->resetAfterTest(); 1604 1605 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1606 1607 $semantics = json_encode( 1608 array( 1609 'type' => 'text', 1610 'name' => 'text', 1611 'label' => 'Plain text', 1612 'description' => 'Please add some text' 1613 ) 1614 ); 1615 1616 // Create a library 'Library1' with semantics. 1617 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2, $semantics); 1618 1619 $updatedsemantics = array( 1620 'type' => 'text', 1621 'name' => 'updated text', 1622 'label' => 'Updated text', 1623 'description' => 'Please add some text' 1624 ); 1625 1626 // Alter the semantics of 'Library1'. 1627 $this->framework->alterLibrarySemantics($updatedsemantics, 'Library1', 1, 1); 1628 1629 // Get the semantics of 'Library1' from the DB. 1630 $currentsemantics = $DB->get_field('h5p_libraries', 'semantics', array('id' => $library1->id)); 1631 1632 // The semantics for Library1 shouldn't be updated. 1633 $this->assertEquals($semantics, $currentsemantics); 1634 } 1635 1636 /** 1637 * Test the behaviour of deleteLibraryDependencies() when requesting to delete the 1638 * dependencies of an existing library. 1639 */ 1640 public function test_deleteLibraryDependencies_existing_library() { 1641 global $DB; 1642 1643 $this->resetAfterTest(); 1644 1645 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1646 1647 // Generate h5p related data. 1648 $data = $generator->generate_h5p_data(); 1649 // The data of the library 'Library1'. 1650 $library1 = $data->lib1->data; 1651 1652 // Get the dependencies of 'Library1'. 1653 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1654 // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4'). 1655 $this->assertCount(3, $dependencies); 1656 1657 // Delete the dependencies of 'Library1'. 1658 $this->framework->deleteLibraryDependencies($library1->id); 1659 1660 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1661 // The 'Library1' should have 0 dependencies. 1662 $this->assertCount(0, $dependencies); 1663 } 1664 1665 /** 1666 * Test the behaviour of deleteLibraryDependencies() when requesting to delete the 1667 * dependencies of a non-existent library. 1668 */ 1669 public function test_deleteLibraryDependencies_non_existent_library() { 1670 global $DB; 1671 1672 $this->resetAfterTest(); 1673 1674 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1675 1676 // Generate h5p related data. 1677 $data = $generator->generate_h5p_data(); 1678 // The data of the library 'Library1'. 1679 $library1 = $data->lib1->data; 1680 1681 // Get the dependencies of 'Library1'. 1682 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1683 // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4'). 1684 $this->assertCount(3, $dependencies); 1685 1686 // Delete the dependencies of a non-existent library. 1687 $this->framework->deleteLibraryDependencies(0); 1688 1689 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1690 // The 'Library1' should have 3 dependencies. 1691 $this->assertCount(3, $dependencies); 1692 } 1693 1694 /** 1695 * Test the behaviour of deleteLibrary(). 1696 */ 1697 public function test_deleteLibrary() { 1698 global $DB; 1699 1700 $this->resetAfterTest(); 1701 1702 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1703 1704 // Generate h5p related data. 1705 $data = $generator->generate_h5p_data(true); 1706 // The data of the 'Library1' library. 1707 $library1 = $data->lib1->data; 1708 1709 // Get the library dependencies of 'Library1'. 1710 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1711 1712 // The 'Library1' should have 3 library dependencies ('Library2', 'Library3', 'Library4'). 1713 $this->assertCount(3, $dependencies); 1714 1715 // Return the created 'Library1' files. 1716 $libraryfiles = $DB->get_records('files', 1717 array( 1718 'component' => \core_h5p\file_storage::COMPONENT, 1719 'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA, 1720 'itemid' => $library1->id 1721 ) 1722 ); 1723 1724 // The library ('Library1') should have 7 related folders/files. 1725 $this->assertCount(7, $libraryfiles); 1726 1727 // Delete the library. 1728 $this->framework->deleteLibrary($library1); 1729 1730 $lib1 = $DB->get_record('h5p_libraries', ['machinename' => $library1->machinename]); 1731 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1732 $libraryfiles = $DB->get_records('files', 1733 array( 1734 'component' => \core_h5p\file_storage::COMPONENT, 1735 'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA, 1736 'itemid' => $library1->id 1737 ) 1738 ); 1739 1740 // The 'Library1' should not exist. 1741 $this->assertEmpty($lib1); 1742 // The library ('Library1') should have 0 dependencies. 1743 $this->assertCount(0, $dependencies); 1744 // The library (library1) should have 0 related folders/files. 1745 $this->assertCount(0, $libraryfiles); 1746 } 1747 1748 /** 1749 * Test the behaviour of loadContent(). 1750 */ 1751 public function test_loadContent() { 1752 global $DB; 1753 1754 $this->resetAfterTest(); 1755 1756 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1757 1758 // Generate h5p related data. 1759 $data = $generator->generate_h5p_data(); 1760 // The Id of the created h5p content. 1761 $h5pid = $data->h5pcontent->h5pid; 1762 // Get the h5p content data from the DB. 1763 $h5p = $DB->get_record('h5p', ['id' => $h5pid]); 1764 // The data of content's main library ('MainLibrary'). 1765 $mainlibrary = $data->mainlib->data; 1766 1767 // Load the h5p content. 1768 $content = $this->framework->loadContent($h5pid); 1769 1770 $expected = array( 1771 'id' => $h5p->id, 1772 'params' => $h5p->jsoncontent, 1773 'embedType' => 'iframe', 1774 'disable' => $h5p->displayoptions, 1775 'title' => $mainlibrary->title, 1776 'slug' => H5PCore::slugify($mainlibrary->title) . '-' . $h5p->id, 1777 'filtered' => $h5p->filtered, 1778 'libraryId' => $mainlibrary->id, 1779 'libraryName' => $mainlibrary->machinename, 1780 'libraryMajorVersion' => $mainlibrary->majorversion, 1781 'libraryMinorVersion' => $mainlibrary->minorversion, 1782 'libraryEmbedTypes' => $mainlibrary->embedtypes, 1783 'libraryFullscreen' => $mainlibrary->fullscreen, 1784 'metadata' => '', 1785 'pathnamehash' => $h5p->pathnamehash 1786 ); 1787 1788 $params = json_decode($h5p->jsoncontent); 1789 if (empty($params->metadata)) { 1790 $params->metadata = new \stdClass(); 1791 } 1792 $expected['metadata'] = $params->metadata; 1793 $expected['params'] = json_encode($params->params ?? $params); 1794 1795 // The returned content should match the expected array. 1796 $this->assertEquals($expected, $content); 1797 } 1798 1799 /** 1800 * Test the behaviour of loadContentDependencies() when requesting content dependencies 1801 * without specifying the dependency type. 1802 */ 1803 public function test_loadContentDependencies_no_type_defined() { 1804 $this->resetAfterTest(); 1805 1806 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1807 1808 // Generate h5p related data. 1809 $data = $generator->generate_h5p_data(); 1810 // The Id of the h5p content. 1811 $h5pid = $data->h5pcontent->h5pid; 1812 // The content dependencies. 1813 $dependencies = $data->h5pcontent->contentdependencies; 1814 1815 // Add Library5 as a content dependency (dynamic dependency type). 1816 $library5 = $data->lib5->data; 1817 $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic'); 1818 1819 // Get all content dependencies. 1820 $contentdependencies = $this->framework->loadContentDependencies($h5pid); 1821 1822 $expected = array(); 1823 foreach ($dependencies as $dependency) { 1824 $expected[$dependency->machinename] = array( 1825 'libraryId' => $dependency->id, 1826 'machineName' => $dependency->machinename, 1827 'majorVersion' => $dependency->majorversion, 1828 'minorVersion' => $dependency->minorversion, 1829 'patchVersion' => $dependency->patchversion, 1830 'preloadedCss' => $dependency->preloadedcss, 1831 'preloadedJs' => $dependency->preloadedjs, 1832 'dropCss' => '0', 1833 'dependencyType' => 'preloaded' 1834 ); 1835 } 1836 1837 $expected = array_merge($expected, 1838 array( 1839 'Library5' => array( 1840 'libraryId' => $library5->id, 1841 'machineName' => $library5->machinename, 1842 'majorVersion' => $library5->majorversion, 1843 'minorVersion' => $library5->minorversion, 1844 'patchVersion' => $library5->patchversion, 1845 'preloadedCss' => $library5->preloadedcss, 1846 'preloadedJs' => $library5->preloadedjs, 1847 'dropCss' => '0', 1848 'dependencyType' => 'dynamic' 1849 ) 1850 ) 1851 ); 1852 1853 // The loaded content dependencies should return 6 libraries. 1854 $this->assertCount(6, $contentdependencies); 1855 $this->assertEquals($expected, $contentdependencies); 1856 } 1857 1858 /** 1859 * Test the behaviour of loadContentDependencies() when requesting content dependencies 1860 * with specifying the dependency type. 1861 */ 1862 public function test_loadContentDependencies_type_defined() { 1863 $this->resetAfterTest(); 1864 1865 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1866 1867 // Generate h5p related data. 1868 $data = $generator->generate_h5p_data(); 1869 // The Id of the h5p content. 1870 $h5pid = $data->h5pcontent->h5pid; 1871 // The content dependencies. 1872 $dependencies = $data->h5pcontent->contentdependencies; 1873 1874 // Add Library5 as a content dependency (dynamic dependency type). 1875 $library5 = $data->lib5->data; 1876 $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic'); 1877 1878 // Load all content dependencies of dependency type 'preloaded'. 1879 $preloadeddependencies = $this->framework->loadContentDependencies($h5pid, 'preloaded'); 1880 1881 $expected = array(); 1882 foreach ($dependencies as $dependency) { 1883 $expected[$dependency->machinename] = array( 1884 'libraryId' => $dependency->id, 1885 'machineName' => $dependency->machinename, 1886 'majorVersion' => $dependency->majorversion, 1887 'minorVersion' => $dependency->minorversion, 1888 'patchVersion' => $dependency->patchversion, 1889 'preloadedCss' => $dependency->preloadedcss, 1890 'preloadedJs' => $dependency->preloadedjs, 1891 'dropCss' => '0', 1892 'dependencyType' => 'preloaded' 1893 ); 1894 } 1895 1896 // The loaded content dependencies should return 5 libraries. 1897 $this->assertCount(5, $preloadeddependencies); 1898 $this->assertEquals($expected, $preloadeddependencies); 1899 1900 // Load all content dependencies of dependency type 'dynamic'. 1901 $dynamicdependencies = $this->framework->loadContentDependencies($h5pid, 'dynamic'); 1902 1903 $expected = array( 1904 'Library5' => array( 1905 'libraryId' => $library5->id, 1906 'machineName' => $library5->machinename, 1907 'majorVersion' => $library5->majorversion, 1908 'minorVersion' => $library5->minorversion, 1909 'patchVersion' => $library5->patchversion, 1910 'preloadedCss' => $library5->preloadedcss, 1911 'preloadedJs' => $library5->preloadedjs, 1912 'dropCss' => '0', 1913 'dependencyType' => 'dynamic' 1914 ) 1915 ); 1916 1917 // The loaded content dependencies should now return 1 library. 1918 $this->assertCount(1, $dynamicdependencies); 1919 $this->assertEquals($expected, $dynamicdependencies); 1920 } 1921 1922 /** 1923 * Test the behaviour of getOption(). 1924 */ 1925 public function test_getOption(): void { 1926 $this->resetAfterTest(); 1927 1928 // Get value for display_option_download. 1929 $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_DOWNLOAD); 1930 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1931 $this->assertEquals($expected, $value); 1932 1933 // Get value for display_option_embed using default value (it should be ignored). 1934 $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_EMBED, H5PDisplayOptionBehaviour::NEVER_SHOW); 1935 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1936 $this->assertEquals($expected, $value); 1937 1938 // Get value for unexisting setting without default. 1939 $value = $this->framework->getOption('unexistingsetting'); 1940 $expected = false; 1941 $this->assertEquals($expected, $value); 1942 1943 // Get value for unexisting setting with default. 1944 $value = $this->framework->getOption('unexistingsetting', 'defaultvalue'); 1945 $expected = 'defaultvalue'; 1946 $this->assertEquals($expected, $value); 1947 } 1948 1949 /** 1950 * Test the behaviour of setOption(). 1951 */ 1952 public function test_setOption(): void { 1953 $this->resetAfterTest(); 1954 1955 // Set value for 'newsetting' setting. 1956 $name = 'newsetting'; 1957 $value = $this->framework->getOption($name); 1958 $this->assertEquals(false, $value); 1959 $newvalue = 'value1'; 1960 $this->framework->setOption($name, $newvalue); 1961 $value = $this->framework->getOption($name); 1962 $this->assertEquals($newvalue, $value); 1963 1964 // Set value for display_option_download and then get it again. Check it hasn't changed. 1965 $name = H5PCore::DISPLAY_OPTION_DOWNLOAD; 1966 $newvalue = H5PDisplayOptionBehaviour::NEVER_SHOW; 1967 $this->framework->setOption($name, $newvalue); 1968 $value = $this->framework->getOption($name); 1969 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1970 $this->assertEquals($expected, $value); 1971 } 1972 1973 /** 1974 * Test the behaviour of updateContentFields(). 1975 */ 1976 public function test_updateContentFields() { 1977 global $DB; 1978 1979 $this->resetAfterTest(); 1980 1981 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1982 1983 // Create 'Library1' library. 1984 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 1985 // Create 'Library2' library. 1986 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 1987 1988 // Create an h5p content with 'Library1' as it's main library. 1989 $h5pid = $generator->create_h5p_record($library1->id, 'iframe'); 1990 1991 $updatedata = array( 1992 'jsoncontent' => json_encode(['value' => 'test']), 1993 'mainlibraryid' => $library2->id 1994 ); 1995 1996 // Update h5p content fields. 1997 $this->framework->updateContentFields($h5pid, $updatedata); 1998 1999 // Get the h5p content from the DB. 2000 $h5p = $DB->get_record('h5p', ['id' => $h5pid]); 2001 2002 $expected = json_encode(['value' => 'test']); 2003 2004 // Make sure the h5p content fields are properly updated. 2005 $this->assertEquals($expected, $h5p->jsoncontent); 2006 $this->assertEquals($library2->id, $h5p->mainlibraryid); 2007 } 2008 2009 /** 2010 * Test the behaviour of clearFilteredParameters(). 2011 */ 2012 public function test_clearFilteredParameters() { 2013 global $DB; 2014 2015 $this->resetAfterTest(); 2016 2017 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2018 2019 // Create 3 libraries. 2020 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 2021 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 2022 $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2); 2023 2024 // Create h5p content with 'Library1' as a main library. 2025 $h5pcontentid1 = $generator->create_h5p_record($library1->id); 2026 // Create h5p content with 'Library1' as a main library. 2027 $h5pcontentid2 = $generator->create_h5p_record($library1->id); 2028 // Create h5p content with 'Library2' as a main library. 2029 $h5pcontentid3 = $generator->create_h5p_record($library2->id); 2030 // Create h5p content with 'Library3' as a main library. 2031 $h5pcontentid4 = $generator->create_h5p_record($library3->id); 2032 2033 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 2034 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 2035 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 2036 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 2037 2038 // The filtered parameters should be present in each h5p content. 2039 $this->assertNotEmpty($h5pcontent1->filtered); 2040 $this->assertNotEmpty($h5pcontent2->filtered); 2041 $this->assertNotEmpty($h5pcontent3->filtered); 2042 $this->assertNotEmpty($h5pcontent4->filtered); 2043 2044 // Clear the filtered parameters for contents that have library1 and library3 as 2045 // their main library. 2046 $this->framework->clearFilteredParameters([$library1->id, $library3->id]); 2047 2048 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 2049 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 2050 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 2051 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 2052 2053 // The filtered parameters should be still present only for the content that has 2054 // library 2 as a main library. 2055 $this->assertEmpty($h5pcontent1->filtered); 2056 $this->assertEmpty($h5pcontent2->filtered); 2057 $this->assertNotEmpty($h5pcontent3->filtered); 2058 $this->assertEmpty($h5pcontent4->filtered); 2059 } 2060 2061 /** 2062 * Test the behaviour of getNumNotFiltered(). 2063 */ 2064 public function test_getNumNotFiltered() { 2065 global $DB; 2066 2067 $this->resetAfterTest(); 2068 2069 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2070 2071 // Create 3 libraries. 2072 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 2073 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 2074 $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2); 2075 2076 // Create h5p content with library1 as a main library. 2077 $h5pcontentid1 = $generator->create_h5p_record($library1->id); 2078 // Create h5p content with library1 as a main library. 2079 $h5pcontentid2 = $generator->create_h5p_record($library1->id); 2080 // Create h5p content with library2 as a main library. 2081 $h5pcontentid3 = $generator->create_h5p_record($library2->id); 2082 // Create h5p content with library3 as a main library. 2083 $h5pcontentid4 = $generator->create_h5p_record($library3->id); 2084 2085 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 2086 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 2087 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 2088 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 2089 2090 // The filtered parameters should be present in each h5p content. 2091 $this->assertNotEmpty($h5pcontent1->filtered); 2092 $this->assertNotEmpty($h5pcontent2->filtered); 2093 $this->assertNotEmpty($h5pcontent3->filtered); 2094 $this->assertNotEmpty($h5pcontent4->filtered); 2095 2096 // Clear the filtered parameters for contents that have library1 and library3 as 2097 // their main library. 2098 $this->framework->clearFilteredParameters([$library1->id, $library3->id]); 2099 2100 $countnotfiltered = $this->framework->getNumNotFiltered(); 2101 2102 // 3 contents don't have their parameters filtered. 2103 $this->assertEquals(3, $countnotfiltered); 2104 } 2105 2106 /** 2107 * Test the behaviour of getNumContent(). 2108 */ 2109 public function test_getNumContent() { 2110 $this->resetAfterTest(); 2111 2112 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2113 2114 // Generate h5p related data. 2115 $data = $generator->generate_h5p_data(); 2116 2117 // The 'MainLibrary' library data. 2118 $mainlibrary = $data->mainlib->data; 2119 2120 // The 'Library1' library data. 2121 $library1 = $data->lib1->data; 2122 2123 // Create new h5p content with MainLibrary as a main library. 2124 $generator->create_h5p_record($mainlibrary->id); 2125 2126 // Get the number of h5p contents that are using 'MainLibrary' as their main library. 2127 $countmainlib = $this->framework->getNumContent($mainlibrary->id); 2128 2129 // Get the number of h5p contents that are using 'Library1' as their main library. 2130 $countlib1 = $this->framework->getNumContent($library1->id); 2131 2132 // Make sure that 2 contents are using MainLibrary as their main library. 2133 $this->assertEquals(2, $countmainlib); 2134 // Make sure that 0 contents are using Library1 as their main library. 2135 $this->assertEquals(0, $countlib1); 2136 } 2137 2138 /** 2139 * Test the behaviour of getNumContent() when certain contents are being skipped. 2140 */ 2141 public function test_getNumContent_skip_content() { 2142 $this->resetAfterTest(); 2143 2144 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2145 2146 // Generate h5p related data. 2147 $data = $generator->generate_h5p_data(); 2148 2149 // The 'MainLibrary' library data. 2150 $mainlibrary = $data->mainlib->data; 2151 2152 // Create new h5p content with MainLibrary as a main library. 2153 $h5pcontentid = $generator->create_h5p_record($mainlibrary->id); 2154 2155 // Get the number of h5p contents that are using 'MainLibrary' as their main library. 2156 // Skip the newly created content $h5pcontentid. 2157 $countmainlib = $this->framework->getNumContent($mainlibrary->id, [$h5pcontentid]); 2158 2159 // Make sure that 1 content is returned instead of 2 ($h5pcontentid being skipped). 2160 $this->assertEquals(1, $countmainlib); 2161 } 2162 2163 /** 2164 * Test the behaviour of isContentSlugAvailable(). 2165 */ 2166 public function test_isContentSlugAvailable() { 2167 $this->resetAfterTest(); 2168 2169 $slug = 'h5p-test-slug-1'; 2170 2171 // Currently this returns always true. The slug is generated as a unique value for 2172 // each h5p content and it is not stored in the h5p content table. 2173 $isslugavailable = $this->framework->isContentSlugAvailable($slug); 2174 2175 $this->assertTrue($isslugavailable); 2176 } 2177 2178 /** 2179 * Test that a record is stored for cached assets. 2180 */ 2181 public function test_saveCachedAssets() { 2182 global $DB; 2183 2184 $this->resetAfterTest(); 2185 2186 $libraries = array( 2187 array( 2188 'machineName' => 'H5P.TestLib', 2189 'libraryId' => 405, 2190 ), 2191 array( 2192 'FontAwesome' => 'FontAwesome', 2193 'libraryId' => 406, 2194 ), 2195 array( 2196 'machineName' => 'H5P.SecondLib', 2197 'libraryId' => 407, 2198 ), 2199 ); 2200 2201 $key = 'testhashkey'; 2202 2203 $this->framework->saveCachedAssets($key, $libraries); 2204 2205 $records = $DB->get_records('h5p_libraries_cachedassets'); 2206 2207 $this->assertCount(3, $records); 2208 } 2209 2210 /** 2211 * Test that the correct libraries are removed from the cached assets table 2212 */ 2213 public function test_deleteCachedAssets() { 2214 global $DB; 2215 2216 $this->resetAfterTest(); 2217 2218 $libraries = array( 2219 array( 2220 'machineName' => 'H5P.TestLib', 2221 'libraryId' => 405, 2222 ), 2223 array( 2224 'FontAwesome' => 'FontAwesome', 2225 'libraryId' => 406, 2226 ), 2227 array( 2228 'machineName' => 'H5P.SecondLib', 2229 'libraryId' => 407, 2230 ), 2231 ); 2232 2233 $key1 = 'testhashkey'; 2234 $this->framework->saveCachedAssets($key1, $libraries); 2235 2236 $libraries = array( 2237 array( 2238 'machineName' => 'H5P.DiffLib', 2239 'libraryId' => 408, 2240 ), 2241 array( 2242 'FontAwesome' => 'FontAwesome', 2243 'libraryId' => 406, 2244 ), 2245 array( 2246 'machineName' => 'H5P.ThirdLib', 2247 'libraryId' => 409, 2248 ), 2249 ); 2250 2251 $key2 = 'secondhashkey'; 2252 $this->framework->saveCachedAssets($key2, $libraries); 2253 2254 $libraries = array( 2255 array( 2256 'machineName' => 'H5P.AnotherDiffLib', 2257 'libraryId' => 410, 2258 ), 2259 array( 2260 'FontAwesome' => 'NotRelated', 2261 'libraryId' => 411, 2262 ), 2263 array( 2264 'machineName' => 'H5P.ForthLib', 2265 'libraryId' => 412, 2266 ), 2267 ); 2268 2269 $key3 = 'threeforthewin'; 2270 $this->framework->saveCachedAssets($key3, $libraries); 2271 2272 $records = $DB->get_records('h5p_libraries_cachedassets'); 2273 $this->assertCount(9, $records); 2274 2275 // Selecting one library id will result in all related library entries also being deleted. 2276 // Going to use the FontAwesome library id. The first two hashes should be returned. 2277 $hashes = $this->framework->deleteCachedAssets(406); 2278 $this->assertCount(2, $hashes); 2279 $index = array_search($key1, $hashes); 2280 $this->assertEquals($key1, $hashes[$index]); 2281 $index = array_search($key2, $hashes); 2282 $this->assertEquals($key2, $hashes[$index]); 2283 $index = array_search($key3, $hashes); 2284 $this->assertFalse($index); 2285 2286 // Check that the records have been removed as well. 2287 $records = $DB->get_records('h5p_libraries_cachedassets'); 2288 $this->assertCount(3, $records); 2289 } 2290 2291 /** 2292 * Test the behaviour of getLibraryContentCount(). 2293 */ 2294 public function test_getLibraryContentCount() { 2295 $this->resetAfterTest(); 2296 2297 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2298 2299 // Generate h5p related data. 2300 $data = $generator->generate_h5p_data(); 2301 2302 // The 'MainLibrary' library data. 2303 $mainlibrary = $data->mainlib->data; 2304 2305 // The 'Library2' library data. 2306 $library2 = $data->lib2->data; 2307 2308 // Create new h5p content with Library2 as it's main library. 2309 $generator->create_h5p_record($library2->id); 2310 2311 // Create new h5p content with MainLibrary as it's main library. 2312 $generator->create_h5p_record($mainlibrary->id); 2313 2314 $countlibrarycontent = $this->framework->getLibraryContentCount(); 2315 2316 $expected = array( 2317 "{$mainlibrary->machinename} {$mainlibrary->majorversion}.{$mainlibrary->minorversion}" => 2, 2318 "{$library2->machinename} {$library2->majorversion}.{$library2->minorversion}" => 1, 2319 ); 2320 2321 // MainLibrary and Library1 are currently main libraries to the existing h5p contents. 2322 // Should return the number of cases where MainLibrary and Library1 are main libraries to an h5p content. 2323 $this->assertEquals($expected, $countlibrarycontent); 2324 } 2325 2326 /** 2327 * Test the behaviour of test_libraryHasUpgrade(). 2328 * 2329 * @dataProvider libraryHasUpgrade_provider 2330 * @param array $libraryrecords Array containing data for the library creation 2331 * @param array $testlibrary Array containing the test library data 2332 * @param bool $expected The expectation whether the library is patched or not 2333 **/ 2334 public function test_libraryHasUpgrade(array $libraryrecords, array $testlibrary, bool $expected): void { 2335 $this->resetAfterTest(); 2336 2337 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2338 2339 foreach ($libraryrecords as $library) { 2340 call_user_func_array([$generator, 'create_library_record'], $library); 2341 } 2342 2343 $this->assertEquals($expected, $this->framework->libraryHasUpgrade($testlibrary)); 2344 } 2345 2346 /** 2347 * Data provider for test_libraryHasUpgrade(). 2348 * 2349 * @return array 2350 */ 2351 public function libraryHasUpgrade_provider(): array { 2352 return [ 2353 'Lower major version; Identical lower version' => [ 2354 [ 2355 ['Library', 'Lib', 2, 2], 2356 ], 2357 [ 2358 'machineName' => 'Library', 2359 'majorVersion' => 1, 2360 'minorVersion' => 2 2361 ], 2362 true, 2363 ], 2364 'Major version identical; Lower minor version' => [ 2365 [ 2366 ['Library', 'Lib', 2, 2], 2367 ], 2368 [ 2369 'machineName' => 'Library', 2370 'majorVersion' => 2, 2371 'minorVersion' => 1 2372 ], 2373 true, 2374 ], 2375 'Major version identical; Minor version identical' => [ 2376 [ 2377 ['Library', 'Lib', 2, 2], 2378 ], 2379 [ 2380 'machineName' => 'Library', 2381 'majorVersion' => 2, 2382 'minorVersion' => 2 2383 ], 2384 false, 2385 ], 2386 'Major version higher; Minor version identical' => [ 2387 [ 2388 ['Library', 'Lib', 2, 2], 2389 ], 2390 [ 2391 'machineName' => 'Library', 2392 'majorVersion' => 3, 2393 'minorVersion' => 2 2394 ], 2395 false, 2396 ], 2397 'Major version identical; Minor version newer' => [ 2398 [ 2399 ['Library', 'Lib', 2, 2], 2400 ], 2401 [ 2402 'machineName' => 'Library', 2403 'majorVersion' => 2, 2404 'minorVersion' => 4 2405 ], 2406 false, 2407 ] 2408 ]; 2409 } 2410 2411 2412 /** 2413 * Test the behaviour of get_latest_library_version(). 2414 */ 2415 public function test_get_latest_library_version() { 2416 global $DB; 2417 2418 $this->resetAfterTest(); 2419 2420 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2421 // Create a library record. 2422 $machinename = 'TestLibrary'; 2423 $lib1 = $generator->create_library_record($machinename, 'Test', 1, 1, 2); 2424 $lib2 = $generator->create_library_record($machinename, 'Test', 1, 2, 1); 2425 2426 $content = array( 2427 'params' => json_encode(['param1' => 'Test']), 2428 'library' => array( 2429 'libraryId' => 0, 2430 'machineName' => 'TestLibrary', 2431 ), 2432 'disable' => 8 2433 ); 2434 2435 // Get the latest id (at this point, should be lib2). 2436 $latestlib = $this->framework->get_latest_library_version($machinename); 2437 $this->assertEquals($lib2->id, $latestlib->id); 2438 2439 // Get the latest id (at this point, should be lib3). 2440 $lib3 = $generator->create_library_record($machinename, 'Test', 2, 1, 0); 2441 $latestlib = $this->framework->get_latest_library_version($machinename); 2442 $this->assertEquals($lib3->id, $latestlib->id); 2443 2444 // Get the latest id (at this point, should be still lib3). 2445 $lib4 = $generator->create_library_record($machinename, 'Test', 1, 1, 3); 2446 $latestlib = $this->framework->get_latest_library_version($machinename); 2447 $this->assertEquals($lib3->id, $latestlib->id); 2448 2449 // Get the latest id (at this point, should be lib5). 2450 $lib5 = $generator->create_library_record($machinename, 'Test', 2, 1, 6); 2451 $latestlib = $this->framework->get_latest_library_version($machinename); 2452 $this->assertEquals($lib5->id, $latestlib->id); 2453 } 2454 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body