See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [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 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1068 1069 // Create a library record. 1070 $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2); 1071 1072 // Create an h5p content with 'TestLibrary' as it's main library. 1073 $contentid = $generator->create_h5p_record($lib->id); 1074 1075 $content = array( 1076 'id' => $contentid, 1077 'params' => json_encode(['param2' => 'Test2']), 1078 'library' => array( 1079 'libraryId' => $lib->id 1080 ), 1081 'disable' => 8 1082 ); 1083 1084 // Update the h5p content. 1085 $this->framework->updateContent($content); 1086 1087 $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]); 1088 1089 // Make sure the h5p content was properly updated. 1090 $this->assertNotEmpty($h5pcontent); 1091 $this->assertEquals($content['params'], $h5pcontent->jsoncontent); 1092 $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid); 1093 $this->assertEquals($content['disable'], $h5pcontent->displayoptions); 1094 } 1095 1096 /** 1097 * Test the behaviour of updateContent() with metadata. 1098 * 1099 * @covers ::updateContent 1100 */ 1101 public function test_updateContent_withmetadata(): void { 1102 global $DB; 1103 1104 $this->resetAfterTest(); 1105 1106 /** @var \core_h5p_generator $generator */ 1107 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1108 1109 // Create a library record. 1110 $lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2); 1111 1112 // Create an h5p content with 'TestLibrary' as it's main library. 1113 $contentid = $generator->create_h5p_record($lib->id); 1114 1115 $params = ['param2' => 'Test2']; 1116 $metadata = [ 1117 'license' => 'CC BY', 1118 'licenseVersion' => '4.0', 1119 'yearFrom' => 2000, 1120 'yearTo' => 2023, 1121 'defaultLanguage' => 'ca', 1122 ]; 1123 $content = [ 1124 'id' => $contentid, 1125 'params' => json_encode($params), 1126 'library' => [ 1127 'libraryId' => $lib->id, 1128 ], 1129 'disable' => 8, 1130 'metadata' => $metadata, 1131 ]; 1132 1133 // Update the h5p content. 1134 $this->framework->updateContent($content); 1135 1136 $h5pcontent = $DB->get_record('h5p', ['id' => $contentid]); 1137 1138 // Make sure the h5p content was properly updated. 1139 $this->assertNotEmpty($h5pcontent); 1140 $this->assertEquals(json_encode(array_merge($params, ['metadata' => $metadata])), $h5pcontent->jsoncontent); 1141 $this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid); 1142 $this->assertEquals($content['disable'], $h5pcontent->displayoptions); 1143 } 1144 1145 /** 1146 * Test the behaviour of saveLibraryDependencies(). 1147 */ 1148 public function test_saveLibraryDependencies() { 1149 global $DB; 1150 1151 $this->resetAfterTest(); 1152 1153 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1154 1155 // Create a library 'Library'. 1156 $library = $generator->create_library_record('Library', 'Title'); 1157 // Create a library 'DependencyLibrary1'. 1158 $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1'); 1159 // Create a library 'DependencyLibrary2'. 1160 $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2'); 1161 1162 $dependencies = array( 1163 array( 1164 'machineName' => $dependency1->machinename, 1165 'majorVersion' => $dependency1->majorversion, 1166 'minorVersion' => $dependency1->minorversion 1167 ), 1168 array( 1169 'machineName' => $dependency2->machinename, 1170 'majorVersion' => $dependency2->majorversion, 1171 'minorVersion' => $dependency2->minorversion 1172 ), 1173 ); 1174 1175 // Set 'DependencyLibrary1' and 'DependencyLibrary2' as library dependencies of 'Library'. 1176 $this->framework->saveLibraryDependencies($library->id, $dependencies, 'preloaded'); 1177 1178 $libdependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library->id], 'id ASC'); 1179 1180 // Make sure the library dependencies for 'Library' are properly set. 1181 $this->assertEquals(2, count($libdependencies)); 1182 $this->assertEquals($dependency1->id, reset($libdependencies)->requiredlibraryid); 1183 $this->assertEquals($dependency2->id, end($libdependencies)->requiredlibraryid); 1184 } 1185 1186 /** 1187 * Test the behaviour of deleteContentData(). 1188 */ 1189 public function test_deleteContentData() { 1190 global $DB; 1191 1192 $this->resetAfterTest(); 1193 1194 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1195 1196 // Generate some h5p related data. 1197 $data = $generator->generate_h5p_data(); 1198 $h5pid = $data->h5pcontent->h5pid; 1199 1200 $h5pcontent = $DB->get_record('h5p', ['id' => $h5pid]); 1201 // Make sure the particular h5p content exists in the DB. 1202 $this->assertNotEmpty($h5pcontent); 1203 1204 // Get the h5p content libraries from the DB. 1205 $h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]); 1206 1207 // Make sure the content libraries exists in the DB. 1208 $this->assertNotEmpty($h5pcontentlibraries); 1209 $this->assertCount(5, $h5pcontentlibraries); 1210 1211 // Delete the h5p content and it's related data. 1212 $this->framework->deleteContentData($h5pid); 1213 1214 $h5pcontent = $DB->get_record('h5p', ['id' => $h5pid]); 1215 $h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]); 1216 1217 // The particular h5p content should no longer exist in the db. 1218 $this->assertEmpty($h5pcontent); 1219 // The particular content libraries should no longer exist in the db. 1220 $this->assertEmpty($h5pcontentlibraries); 1221 } 1222 1223 /** 1224 * Test the behaviour of deleteLibraryUsage(). 1225 */ 1226 public function test_deleteLibraryUsage() { 1227 global $DB; 1228 1229 $this->resetAfterTest(); 1230 1231 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1232 1233 // Generate some h5p related data. 1234 $data = $generator->generate_h5p_data(); 1235 $h5pid = $data->h5pcontent->h5pid; 1236 1237 // Get the h5p content libraries from the DB. 1238 $h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]); 1239 1240 // The particular h5p content should have 5 content libraries. 1241 $this->assertNotEmpty($h5pcontentlibraries); 1242 $this->assertCount(5, $h5pcontentlibraries); 1243 1244 // Delete the h5p content and it's related data. 1245 $this->framework->deleteLibraryUsage($h5pid); 1246 1247 // Get the h5p content libraries from the DB. 1248 $h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]); 1249 1250 // The particular h5p content libraries should no longer exist in the db. 1251 $this->assertEmpty($h5pcontentlibraries); 1252 } 1253 1254 /** 1255 * Test the behaviour of test_saveLibraryUsage(). 1256 */ 1257 public function test_saveLibraryUsage() { 1258 global $DB; 1259 1260 $this->resetAfterTest(); 1261 1262 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1263 1264 // Create a library 'Library'. 1265 $library = $generator->create_library_record('Library', 'Title'); 1266 // Create a library 'DependencyLibrary1'. 1267 $dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1'); 1268 // Create a library 'DependencyLibrary2'. 1269 $dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2'); 1270 // Create an h5p content with 'Library' as it's main library. 1271 $contentid = $generator->create_h5p_record($library->id); 1272 1273 $dependencies = array( 1274 array( 1275 'library' => array( 1276 'libraryId' => $dependency1->id, 1277 'machineName' => $dependency1->machinename, 1278 'dropLibraryCss' => $dependency1->droplibrarycss 1279 ), 1280 'type' => 'preloaded', 1281 'weight' => 1 1282 ), 1283 array( 1284 'library' => array( 1285 'libraryId' => $dependency2->id, 1286 'machineName' => $dependency2->machinename, 1287 'dropLibraryCss' => $dependency2->droplibrarycss 1288 ), 1289 'type' => 'preloaded', 1290 'weight' => 2 1291 ), 1292 ); 1293 1294 // Save 'DependencyLibrary1' and 'DependencyLibrary2' as h5p content libraries. 1295 $this->framework->saveLibraryUsage($contentid, $dependencies); 1296 1297 // Get the h5p content libraries from the DB. 1298 $libdependencies = $DB->get_records('h5p_contents_libraries', ['h5pid' => $contentid], 'id ASC'); 1299 1300 // Make sure that 'DependencyLibrary1' and 'DependencyLibrary2' are properly set as h5p content libraries. 1301 $this->assertEquals(2, count($libdependencies)); 1302 $this->assertEquals($dependency1->id, reset($libdependencies)->libraryid); 1303 $this->assertEquals($dependency2->id, end($libdependencies)->libraryid); 1304 } 1305 1306 /** 1307 * Test the behaviour of getLibraryUsage() without skipping a particular h5p content. 1308 */ 1309 public function test_getLibraryUsage_no_skip_content() { 1310 $this->resetAfterTest(); 1311 1312 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1313 1314 // Generate h5p related data. 1315 $generateddata = $generator->generate_h5p_data(); 1316 // The Id of the library 'Library1'. 1317 $library1id = $generateddata->lib1->data->id; 1318 // The Id of the library 'Library2'. 1319 $library2id = $generateddata->lib2->data->id; 1320 // The Id of the library 'Library5'. 1321 $library5id = $generateddata->lib5->data->id; 1322 1323 // Get the library usage for 'Library1' (do not skip content). 1324 $data = $this->framework->getLibraryUsage($library1id); 1325 1326 $expected = array( 1327 'content' => 1, 1328 'libraries' => 1 1329 ); 1330 1331 // Make sure 'Library1' is used by 1 content and is a dependency to 1 library. 1332 $this->assertEquals($expected, $data); 1333 1334 // Get the library usage for 'Library2' (do not skip content). 1335 $data = $this->framework->getLibraryUsage($library2id); 1336 1337 $expected = array( 1338 'content' => 1, 1339 'libraries' => 2, 1340 ); 1341 1342 // Make sure 'Library2' is used by 1 content and is a dependency to 2 libraries. 1343 $this->assertEquals($expected, $data); 1344 1345 // Get the library usage for 'Library5' (do not skip content). 1346 $data = $this->framework->getLibraryUsage($library5id); 1347 1348 $expected = array( 1349 'content' => 0, 1350 'libraries' => 1, 1351 ); 1352 1353 // Make sure 'Library5' is not used by any content and is a dependency to 1 library. 1354 $this->assertEquals($expected, $data); 1355 } 1356 1357 /** 1358 * Test the behaviour of getLibraryUsage() when skipping a particular content. 1359 */ 1360 public function test_getLibraryUsage_skip_content() { 1361 $this->resetAfterTest(); 1362 1363 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1364 1365 // Generate h5p related data. 1366 $generateddata = $generator->generate_h5p_data(); 1367 // The Id of the library 'Library1'. 1368 $library1id = $generateddata->lib1->data->id; 1369 1370 // Get the library usage for 'Library1' (skip content). 1371 $data = $this->framework->getLibraryUsage($library1id, true); 1372 $expected = array( 1373 'content' => -1, 1374 'libraries' => 1, 1375 ); 1376 1377 // Make sure 'Library1' is a dependency to 1 library. 1378 $this->assertEquals($expected, $data); 1379 } 1380 1381 /** 1382 * Test the behaviour of loadLibrary() when requesting an existing library. 1383 */ 1384 public function test_loadLibrary_existing_library() { 1385 $this->resetAfterTest(); 1386 1387 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1388 1389 // Generate h5p related data. 1390 $generateddata = $generator->generate_h5p_data(); 1391 // The library data of 'Library1'. 1392 $library1 = $generateddata->lib1->data; 1393 // The library data of 'Library5'. 1394 $library5 = $generateddata->lib5->data; 1395 1396 // The preloaded dependencies. 1397 $preloadeddependencies = array(); 1398 1399 foreach ($generateddata->lib1->dependencies as $preloadeddependency) { 1400 $preloadeddependencies[] = array( 1401 'machineName' => $preloadeddependency->machinename, 1402 'majorVersion' => $preloadeddependency->majorversion, 1403 'minorVersion' => $preloadeddependency->minorversion 1404 ); 1405 } 1406 1407 // Create a dynamic dependency. 1408 $generator->create_library_dependency_record($library1->id, $library5->id, 'dynamic'); 1409 1410 $dynamicdependencies[] = array( 1411 'machineName' => $library5->machinename, 1412 'majorVersion' => $library5->majorversion, 1413 'minorVersion' => $library5->minorversion 1414 ); 1415 1416 // Load 'Library1' data. 1417 $data = $this->framework->loadLibrary($library1->machinename, $library1->majorversion, 1418 $library1->minorversion); 1419 1420 $expected = array( 1421 'libraryId' => $library1->id, 1422 'title' => $library1->title, 1423 'machineName' => $library1->machinename, 1424 'majorVersion' => $library1->majorversion, 1425 'minorVersion' => $library1->minorversion, 1426 'patchVersion' => $library1->patchversion, 1427 'runnable' => $library1->runnable, 1428 'fullscreen' => $library1->fullscreen, 1429 'embedTypes' => $library1->embedtypes, 1430 'preloadedJs' => $library1->preloadedjs, 1431 'preloadedCss' => $library1->preloadedcss, 1432 'dropLibraryCss' => $library1->droplibrarycss, 1433 'semantics' => $library1->semantics, 1434 'preloadedDependencies' => $preloadeddependencies, 1435 'dynamicDependencies' => $dynamicdependencies 1436 ); 1437 1438 // Make sure the 'Library1' data is properly loaded. 1439 $this->assertEquals($expected, $data); 1440 } 1441 1442 /** 1443 * Test the behaviour of loadLibrary() when requesting a non-existent library. 1444 */ 1445 public function test_loadLibrary_non_existent_library() { 1446 $this->resetAfterTest(); 1447 1448 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1449 1450 // Generate h5p related data. 1451 $generator->generate_h5p_data(); 1452 1453 // Attempt to load a non-existent library. 1454 $data = $this->framework->loadLibrary('MissingLibrary', 1, 2); 1455 1456 // Make sure nothing is loaded. 1457 $this->assertFalse($data); 1458 } 1459 1460 /** 1461 * Test the behaviour of loadLibrarySemantics(). 1462 * 1463 * @dataProvider loadLibrarySemantics_provider 1464 * @param array $libraryrecords Array containing data for the library creation 1465 * @param array $testlibrary Array containing the test library data 1466 * @param string $expected The expected semantics value 1467 **/ 1468 public function test_loadLibrarySemantics(array $libraryrecords, array $testlibrary, string $expected): void { 1469 $this->resetAfterTest(); 1470 1471 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1472 1473 foreach ($libraryrecords as $library) { 1474 call_user_func_array([$generator, 'create_library_record'], $library); 1475 } 1476 1477 $this->assertEquals($expected, $this->framework->loadLibrarySemantics( 1478 $testlibrary['machinename'], $testlibrary['majorversion'], $testlibrary['minorversion'])); 1479 } 1480 1481 /** 1482 * Data provider for test_loadLibrarySemantics(). 1483 * 1484 * @return array 1485 */ 1486 public function loadLibrarySemantics_provider(): array { 1487 1488 $semantics = json_encode( 1489 [ 1490 'type' => 'text', 1491 'name' => 'text', 1492 'label' => 'Plain text', 1493 'description' => 'Please add some text' 1494 ] 1495 ); 1496 1497 return [ 1498 'Library with semantics' => [ 1499 [ 1500 ['Library1', 'Lib1', 1, 1, 2, $semantics], 1501 ], 1502 [ 1503 'machinename' => 'Library1', 1504 'majorversion' => 1, 1505 'minorversion' => 1 1506 ], 1507 $semantics, 1508 ], 1509 'Library without semantics' => [ 1510 [ 1511 ['Library2', 'Lib2', 1, 2, 2, ''], 1512 ], 1513 [ 1514 'machinename' => 'Library2', 1515 'majorversion' => 1, 1516 'minorversion' => 2 1517 ], 1518 '', 1519 ] 1520 ]; 1521 } 1522 1523 /** 1524 * Test the behaviour of alterLibrarySemantics(). 1525 */ 1526 public function test_alterLibrarySemantics() { 1527 global $DB; 1528 1529 $this->resetAfterTest(); 1530 1531 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1532 1533 $semantics = json_encode( 1534 array( 1535 'type' => 'text', 1536 'name' => 'text', 1537 'label' => 'Plain text', 1538 'description' => 'Please add some text' 1539 ) 1540 ); 1541 1542 // Create a library 'Library1' with semantics. 1543 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2, $semantics); 1544 1545 $updatedsemantics = array( 1546 'type' => 'text', 1547 'name' => 'updated text', 1548 'label' => 'Updated text', 1549 'description' => 'Please add some text' 1550 ); 1551 1552 // Alter the semantics of 'Library1'. 1553 $this->framework->alterLibrarySemantics($updatedsemantics, 'Library1', 1, 1); 1554 1555 // Get the semantics of 'Library1' from the DB. 1556 $currentsemantics = $DB->get_field('h5p_libraries', 'semantics', array('id' => $library1->id)); 1557 1558 // The semantics for Library1 shouldn't be updated. 1559 $this->assertEquals($semantics, $currentsemantics); 1560 } 1561 1562 /** 1563 * Test the behaviour of deleteLibraryDependencies() when requesting to delete the 1564 * dependencies of an existing library. 1565 */ 1566 public function test_deleteLibraryDependencies_existing_library() { 1567 global $DB; 1568 1569 $this->resetAfterTest(); 1570 1571 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1572 1573 // Generate h5p related data. 1574 $data = $generator->generate_h5p_data(); 1575 // The data of the library 'Library1'. 1576 $library1 = $data->lib1->data; 1577 1578 // Get the dependencies of 'Library1'. 1579 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1580 // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4'). 1581 $this->assertCount(3, $dependencies); 1582 1583 // Delete the dependencies of 'Library1'. 1584 $this->framework->deleteLibraryDependencies($library1->id); 1585 1586 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1587 // The 'Library1' should have 0 dependencies. 1588 $this->assertCount(0, $dependencies); 1589 } 1590 1591 /** 1592 * Test the behaviour of deleteLibraryDependencies() when requesting to delete the 1593 * dependencies of a non-existent library. 1594 */ 1595 public function test_deleteLibraryDependencies_non_existent_library() { 1596 global $DB; 1597 1598 $this->resetAfterTest(); 1599 1600 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1601 1602 // Generate h5p related data. 1603 $data = $generator->generate_h5p_data(); 1604 // The data of the library 'Library1'. 1605 $library1 = $data->lib1->data; 1606 1607 // Get the dependencies of 'Library1'. 1608 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1609 // The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4'). 1610 $this->assertCount(3, $dependencies); 1611 1612 // Delete the dependencies of a non-existent library. 1613 $this->framework->deleteLibraryDependencies(0); 1614 1615 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1616 // The 'Library1' should have 3 dependencies. 1617 $this->assertCount(3, $dependencies); 1618 } 1619 1620 /** 1621 * Test the behaviour of deleteLibrary(). 1622 */ 1623 public function test_deleteLibrary() { 1624 global $DB; 1625 1626 $this->resetAfterTest(); 1627 1628 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1629 1630 // Generate h5p related data. 1631 $data = $generator->generate_h5p_data(true); 1632 // The data of the 'Library1' library. 1633 $library1 = $data->lib1->data; 1634 1635 // Get the library dependencies of 'Library1'. 1636 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1637 1638 // The 'Library1' should have 3 library dependencies ('Library2', 'Library3', 'Library4'). 1639 $this->assertCount(3, $dependencies); 1640 1641 // Return the created 'Library1' files. 1642 $libraryfiles = $DB->get_records('files', 1643 array( 1644 'component' => \core_h5p\file_storage::COMPONENT, 1645 'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA, 1646 'itemid' => $library1->id 1647 ) 1648 ); 1649 1650 // The library ('Library1') should have 7 related folders/files. 1651 $this->assertCount(7, $libraryfiles); 1652 1653 // Delete the library. 1654 $this->framework->deleteLibrary($library1); 1655 1656 $lib1 = $DB->get_record('h5p_libraries', ['machinename' => $library1->machinename]); 1657 $dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]); 1658 $libraryfiles = $DB->get_records('files', 1659 array( 1660 'component' => \core_h5p\file_storage::COMPONENT, 1661 'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA, 1662 'itemid' => $library1->id 1663 ) 1664 ); 1665 1666 // The 'Library1' should not exist. 1667 $this->assertEmpty($lib1); 1668 // The library ('Library1') should have 0 dependencies. 1669 $this->assertCount(0, $dependencies); 1670 // The library (library1) should have 0 related folders/files. 1671 $this->assertCount(0, $libraryfiles); 1672 } 1673 1674 /** 1675 * Test the behaviour of loadContent(). 1676 */ 1677 public function test_loadContent() { 1678 global $DB; 1679 1680 $this->resetAfterTest(); 1681 1682 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1683 1684 // Generate h5p related data. 1685 $data = $generator->generate_h5p_data(); 1686 // The Id of the created h5p content. 1687 $h5pid = $data->h5pcontent->h5pid; 1688 // Get the h5p content data from the DB. 1689 $h5p = $DB->get_record('h5p', ['id' => $h5pid]); 1690 // The data of content's main library ('MainLibrary'). 1691 $mainlibrary = $data->mainlib->data; 1692 1693 // Load the h5p content. 1694 $content = $this->framework->loadContent($h5pid); 1695 1696 $expected = array( 1697 'id' => $h5p->id, 1698 'params' => $h5p->jsoncontent, 1699 'embedType' => 'iframe', 1700 'disable' => $h5p->displayoptions, 1701 'title' => $mainlibrary->title, 1702 'slug' => H5PCore::slugify($mainlibrary->title) . '-' . $h5p->id, 1703 'filtered' => $h5p->filtered, 1704 'libraryId' => $mainlibrary->id, 1705 'libraryName' => $mainlibrary->machinename, 1706 'libraryMajorVersion' => $mainlibrary->majorversion, 1707 'libraryMinorVersion' => $mainlibrary->minorversion, 1708 'libraryEmbedTypes' => $mainlibrary->embedtypes, 1709 'libraryFullscreen' => $mainlibrary->fullscreen, 1710 'metadata' => '', 1711 'pathnamehash' => $h5p->pathnamehash 1712 ); 1713 1714 $params = json_decode($h5p->jsoncontent); 1715 if (empty($params->metadata)) { 1716 $params->metadata = new \stdClass(); 1717 } 1718 $expected['metadata'] = $params->metadata; 1719 $expected['params'] = json_encode($params->params ?? $params); 1720 1721 // The returned content should match the expected array. 1722 $this->assertEquals($expected, $content); 1723 } 1724 1725 /** 1726 * Test the behaviour of loadContentDependencies() when requesting content dependencies 1727 * without specifying the dependency type. 1728 */ 1729 public function test_loadContentDependencies_no_type_defined() { 1730 $this->resetAfterTest(); 1731 1732 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1733 1734 // Generate h5p related data. 1735 $data = $generator->generate_h5p_data(); 1736 // The Id of the h5p content. 1737 $h5pid = $data->h5pcontent->h5pid; 1738 // The content dependencies. 1739 $dependencies = $data->h5pcontent->contentdependencies; 1740 1741 // Add Library5 as a content dependency (dynamic dependency type). 1742 $library5 = $data->lib5->data; 1743 $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic'); 1744 1745 // Get all content dependencies. 1746 $contentdependencies = $this->framework->loadContentDependencies($h5pid); 1747 1748 $expected = array(); 1749 foreach ($dependencies as $dependency) { 1750 $expected[$dependency->machinename] = array( 1751 'libraryId' => $dependency->id, 1752 'machineName' => $dependency->machinename, 1753 'majorVersion' => $dependency->majorversion, 1754 'minorVersion' => $dependency->minorversion, 1755 'patchVersion' => $dependency->patchversion, 1756 'preloadedCss' => $dependency->preloadedcss, 1757 'preloadedJs' => $dependency->preloadedjs, 1758 'dropCss' => '0', 1759 'dependencyType' => 'preloaded' 1760 ); 1761 } 1762 1763 $expected = array_merge($expected, 1764 array( 1765 'Library5' => array( 1766 'libraryId' => $library5->id, 1767 'machineName' => $library5->machinename, 1768 'majorVersion' => $library5->majorversion, 1769 'minorVersion' => $library5->minorversion, 1770 'patchVersion' => $library5->patchversion, 1771 'preloadedCss' => $library5->preloadedcss, 1772 'preloadedJs' => $library5->preloadedjs, 1773 'dropCss' => '0', 1774 'dependencyType' => 'dynamic' 1775 ) 1776 ) 1777 ); 1778 1779 // The loaded content dependencies should return 6 libraries. 1780 $this->assertCount(6, $contentdependencies); 1781 $this->assertEquals($expected, $contentdependencies); 1782 } 1783 1784 /** 1785 * Test the behaviour of loadContentDependencies() when requesting content dependencies 1786 * with specifying the dependency type. 1787 */ 1788 public function test_loadContentDependencies_type_defined() { 1789 $this->resetAfterTest(); 1790 1791 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1792 1793 // Generate h5p related data. 1794 $data = $generator->generate_h5p_data(); 1795 // The Id of the h5p content. 1796 $h5pid = $data->h5pcontent->h5pid; 1797 // The content dependencies. 1798 $dependencies = $data->h5pcontent->contentdependencies; 1799 1800 // Add Library5 as a content dependency (dynamic dependency type). 1801 $library5 = $data->lib5->data; 1802 $generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic'); 1803 1804 // Load all content dependencies of dependency type 'preloaded'. 1805 $preloadeddependencies = $this->framework->loadContentDependencies($h5pid, 'preloaded'); 1806 1807 $expected = array(); 1808 foreach ($dependencies as $dependency) { 1809 $expected[$dependency->machinename] = array( 1810 'libraryId' => $dependency->id, 1811 'machineName' => $dependency->machinename, 1812 'majorVersion' => $dependency->majorversion, 1813 'minorVersion' => $dependency->minorversion, 1814 'patchVersion' => $dependency->patchversion, 1815 'preloadedCss' => $dependency->preloadedcss, 1816 'preloadedJs' => $dependency->preloadedjs, 1817 'dropCss' => '0', 1818 'dependencyType' => 'preloaded' 1819 ); 1820 } 1821 1822 // The loaded content dependencies should return 5 libraries. 1823 $this->assertCount(5, $preloadeddependencies); 1824 $this->assertEquals($expected, $preloadeddependencies); 1825 1826 // Load all content dependencies of dependency type 'dynamic'. 1827 $dynamicdependencies = $this->framework->loadContentDependencies($h5pid, 'dynamic'); 1828 1829 $expected = array( 1830 'Library5' => array( 1831 'libraryId' => $library5->id, 1832 'machineName' => $library5->machinename, 1833 'majorVersion' => $library5->majorversion, 1834 'minorVersion' => $library5->minorversion, 1835 'patchVersion' => $library5->patchversion, 1836 'preloadedCss' => $library5->preloadedcss, 1837 'preloadedJs' => $library5->preloadedjs, 1838 'dropCss' => '0', 1839 'dependencyType' => 'dynamic' 1840 ) 1841 ); 1842 1843 // The loaded content dependencies should now return 1 library. 1844 $this->assertCount(1, $dynamicdependencies); 1845 $this->assertEquals($expected, $dynamicdependencies); 1846 } 1847 1848 /** 1849 * Test the behaviour of getOption(). 1850 */ 1851 public function test_getOption(): void { 1852 $this->resetAfterTest(); 1853 1854 // Get value for display_option_download. 1855 $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_DOWNLOAD); 1856 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1857 $this->assertEquals($expected, $value); 1858 1859 // Get value for display_option_embed using default value (it should be ignored). 1860 $value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_EMBED, H5PDisplayOptionBehaviour::NEVER_SHOW); 1861 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1862 $this->assertEquals($expected, $value); 1863 1864 // Get value for unexisting setting without default. 1865 $value = $this->framework->getOption('unexistingsetting'); 1866 $expected = false; 1867 $this->assertEquals($expected, $value); 1868 1869 // Get value for unexisting setting with default. 1870 $value = $this->framework->getOption('unexistingsetting', 'defaultvalue'); 1871 $expected = 'defaultvalue'; 1872 $this->assertEquals($expected, $value); 1873 } 1874 1875 /** 1876 * Test the behaviour of setOption(). 1877 */ 1878 public function test_setOption(): void { 1879 $this->resetAfterTest(); 1880 1881 // Set value for 'newsetting' setting. 1882 $name = 'newsetting'; 1883 $value = $this->framework->getOption($name); 1884 $this->assertEquals(false, $value); 1885 $newvalue = 'value1'; 1886 $this->framework->setOption($name, $newvalue); 1887 $value = $this->framework->getOption($name); 1888 $this->assertEquals($newvalue, $value); 1889 1890 // Set value for display_option_download and then get it again. Check it hasn't changed. 1891 $name = H5PCore::DISPLAY_OPTION_DOWNLOAD; 1892 $newvalue = H5PDisplayOptionBehaviour::NEVER_SHOW; 1893 $this->framework->setOption($name, $newvalue); 1894 $value = $this->framework->getOption($name); 1895 $expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF; 1896 $this->assertEquals($expected, $value); 1897 } 1898 1899 /** 1900 * Test the behaviour of updateContentFields(). 1901 */ 1902 public function test_updateContentFields() { 1903 global $DB; 1904 1905 $this->resetAfterTest(); 1906 1907 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1908 1909 // Create 'Library1' library. 1910 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 1911 // Create 'Library2' library. 1912 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 1913 1914 // Create an h5p content with 'Library1' as it's main library. 1915 $h5pid = $generator->create_h5p_record($library1->id, 'iframe'); 1916 1917 $updatedata = array( 1918 'jsoncontent' => json_encode(['value' => 'test']), 1919 'mainlibraryid' => $library2->id 1920 ); 1921 1922 // Update h5p content fields. 1923 $this->framework->updateContentFields($h5pid, $updatedata); 1924 1925 // Get the h5p content from the DB. 1926 $h5p = $DB->get_record('h5p', ['id' => $h5pid]); 1927 1928 $expected = json_encode(['value' => 'test']); 1929 1930 // Make sure the h5p content fields are properly updated. 1931 $this->assertEquals($expected, $h5p->jsoncontent); 1932 $this->assertEquals($library2->id, $h5p->mainlibraryid); 1933 } 1934 1935 /** 1936 * Test the behaviour of clearFilteredParameters(). 1937 */ 1938 public function test_clearFilteredParameters() { 1939 global $DB; 1940 1941 $this->resetAfterTest(); 1942 1943 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1944 1945 // Create 3 libraries. 1946 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 1947 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 1948 $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2); 1949 1950 // Create h5p content with 'Library1' as a main library. 1951 $h5pcontentid1 = $generator->create_h5p_record($library1->id); 1952 // Create h5p content with 'Library1' as a main library. 1953 $h5pcontentid2 = $generator->create_h5p_record($library1->id); 1954 // Create h5p content with 'Library2' as a main library. 1955 $h5pcontentid3 = $generator->create_h5p_record($library2->id); 1956 // Create h5p content with 'Library3' as a main library. 1957 $h5pcontentid4 = $generator->create_h5p_record($library3->id); 1958 1959 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 1960 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 1961 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 1962 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 1963 1964 // The filtered parameters should be present in each h5p content. 1965 $this->assertNotEmpty($h5pcontent1->filtered); 1966 $this->assertNotEmpty($h5pcontent2->filtered); 1967 $this->assertNotEmpty($h5pcontent3->filtered); 1968 $this->assertNotEmpty($h5pcontent4->filtered); 1969 1970 // Clear the filtered parameters for contents that have library1 and library3 as 1971 // their main library. 1972 $this->framework->clearFilteredParameters([$library1->id, $library3->id]); 1973 1974 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 1975 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 1976 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 1977 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 1978 1979 // The filtered parameters should be still present only for the content that has 1980 // library 2 as a main library. 1981 $this->assertEmpty($h5pcontent1->filtered); 1982 $this->assertEmpty($h5pcontent2->filtered); 1983 $this->assertNotEmpty($h5pcontent3->filtered); 1984 $this->assertEmpty($h5pcontent4->filtered); 1985 } 1986 1987 /** 1988 * Test the behaviour of getNumNotFiltered(). 1989 */ 1990 public function test_getNumNotFiltered() { 1991 global $DB; 1992 1993 $this->resetAfterTest(); 1994 1995 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 1996 1997 // Create 3 libraries. 1998 $library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2); 1999 $library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2); 2000 $library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2); 2001 2002 // Create h5p content with library1 as a main library. 2003 $h5pcontentid1 = $generator->create_h5p_record($library1->id); 2004 // Create h5p content with library1 as a main library. 2005 $h5pcontentid2 = $generator->create_h5p_record($library1->id); 2006 // Create h5p content with library2 as a main library. 2007 $h5pcontentid3 = $generator->create_h5p_record($library2->id); 2008 // Create h5p content with library3 as a main library. 2009 $h5pcontentid4 = $generator->create_h5p_record($library3->id); 2010 2011 $h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]); 2012 $h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]); 2013 $h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]); 2014 $h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]); 2015 2016 // The filtered parameters should be present in each h5p content. 2017 $this->assertNotEmpty($h5pcontent1->filtered); 2018 $this->assertNotEmpty($h5pcontent2->filtered); 2019 $this->assertNotEmpty($h5pcontent3->filtered); 2020 $this->assertNotEmpty($h5pcontent4->filtered); 2021 2022 // Clear the filtered parameters for contents that have library1 and library3 as 2023 // their main library. 2024 $this->framework->clearFilteredParameters([$library1->id, $library3->id]); 2025 2026 $countnotfiltered = $this->framework->getNumNotFiltered(); 2027 2028 // 3 contents don't have their parameters filtered. 2029 $this->assertEquals(3, $countnotfiltered); 2030 } 2031 2032 /** 2033 * Test the behaviour of getNumContent(). 2034 */ 2035 public function test_getNumContent() { 2036 $this->resetAfterTest(); 2037 2038 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2039 2040 // Generate h5p related data. 2041 $data = $generator->generate_h5p_data(); 2042 2043 // The 'MainLibrary' library data. 2044 $mainlibrary = $data->mainlib->data; 2045 2046 // The 'Library1' library data. 2047 $library1 = $data->lib1->data; 2048 2049 // Create new h5p content with MainLibrary as a main library. 2050 $generator->create_h5p_record($mainlibrary->id); 2051 2052 // Get the number of h5p contents that are using 'MainLibrary' as their main library. 2053 $countmainlib = $this->framework->getNumContent($mainlibrary->id); 2054 2055 // Get the number of h5p contents that are using 'Library1' as their main library. 2056 $countlib1 = $this->framework->getNumContent($library1->id); 2057 2058 // Make sure that 2 contents are using MainLibrary as their main library. 2059 $this->assertEquals(2, $countmainlib); 2060 // Make sure that 0 contents are using Library1 as their main library. 2061 $this->assertEquals(0, $countlib1); 2062 } 2063 2064 /** 2065 * Test the behaviour of getNumContent() when certain contents are being skipped. 2066 */ 2067 public function test_getNumContent_skip_content() { 2068 $this->resetAfterTest(); 2069 2070 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2071 2072 // Generate h5p related data. 2073 $data = $generator->generate_h5p_data(); 2074 2075 // The 'MainLibrary' library data. 2076 $mainlibrary = $data->mainlib->data; 2077 2078 // Create new h5p content with MainLibrary as a main library. 2079 $h5pcontentid = $generator->create_h5p_record($mainlibrary->id); 2080 2081 // Get the number of h5p contents that are using 'MainLibrary' as their main library. 2082 // Skip the newly created content $h5pcontentid. 2083 $countmainlib = $this->framework->getNumContent($mainlibrary->id, [$h5pcontentid]); 2084 2085 // Make sure that 1 content is returned instead of 2 ($h5pcontentid being skipped). 2086 $this->assertEquals(1, $countmainlib); 2087 } 2088 2089 /** 2090 * Test the behaviour of isContentSlugAvailable(). 2091 */ 2092 public function test_isContentSlugAvailable() { 2093 $this->resetAfterTest(); 2094 2095 $slug = 'h5p-test-slug-1'; 2096 2097 // Currently this returns always true. The slug is generated as a unique value for 2098 // each h5p content and it is not stored in the h5p content table. 2099 $isslugavailable = $this->framework->isContentSlugAvailable($slug); 2100 2101 $this->assertTrue($isslugavailable); 2102 } 2103 2104 /** 2105 * Test that a record is stored for cached assets. 2106 */ 2107 public function test_saveCachedAssets() { 2108 global $DB; 2109 2110 $this->resetAfterTest(); 2111 2112 $libraries = array( 2113 array( 2114 'machineName' => 'H5P.TestLib', 2115 'libraryId' => 405, 2116 ), 2117 array( 2118 'FontAwesome' => 'FontAwesome', 2119 'libraryId' => 406, 2120 ), 2121 array( 2122 'machineName' => 'H5P.SecondLib', 2123 'libraryId' => 407, 2124 ), 2125 ); 2126 2127 $key = 'testhashkey'; 2128 2129 $this->framework->saveCachedAssets($key, $libraries); 2130 2131 $records = $DB->get_records('h5p_libraries_cachedassets'); 2132 2133 $this->assertCount(3, $records); 2134 } 2135 2136 /** 2137 * Test that the correct libraries are removed from the cached assets table 2138 */ 2139 public function test_deleteCachedAssets() { 2140 global $DB; 2141 2142 $this->resetAfterTest(); 2143 2144 $libraries = array( 2145 array( 2146 'machineName' => 'H5P.TestLib', 2147 'libraryId' => 405, 2148 ), 2149 array( 2150 'FontAwesome' => 'FontAwesome', 2151 'libraryId' => 406, 2152 ), 2153 array( 2154 'machineName' => 'H5P.SecondLib', 2155 'libraryId' => 407, 2156 ), 2157 ); 2158 2159 $key1 = 'testhashkey'; 2160 $this->framework->saveCachedAssets($key1, $libraries); 2161 2162 $libraries = array( 2163 array( 2164 'machineName' => 'H5P.DiffLib', 2165 'libraryId' => 408, 2166 ), 2167 array( 2168 'FontAwesome' => 'FontAwesome', 2169 'libraryId' => 406, 2170 ), 2171 array( 2172 'machineName' => 'H5P.ThirdLib', 2173 'libraryId' => 409, 2174 ), 2175 ); 2176 2177 $key2 = 'secondhashkey'; 2178 $this->framework->saveCachedAssets($key2, $libraries); 2179 2180 $libraries = array( 2181 array( 2182 'machineName' => 'H5P.AnotherDiffLib', 2183 'libraryId' => 410, 2184 ), 2185 array( 2186 'FontAwesome' => 'NotRelated', 2187 'libraryId' => 411, 2188 ), 2189 array( 2190 'machineName' => 'H5P.ForthLib', 2191 'libraryId' => 412, 2192 ), 2193 ); 2194 2195 $key3 = 'threeforthewin'; 2196 $this->framework->saveCachedAssets($key3, $libraries); 2197 2198 $records = $DB->get_records('h5p_libraries_cachedassets'); 2199 $this->assertCount(9, $records); 2200 2201 // Selecting one library id will result in all related library entries also being deleted. 2202 // Going to use the FontAwesome library id. The first two hashes should be returned. 2203 $hashes = $this->framework->deleteCachedAssets(406); 2204 $this->assertCount(2, $hashes); 2205 $index = array_search($key1, $hashes); 2206 $this->assertEquals($key1, $hashes[$index]); 2207 $index = array_search($key2, $hashes); 2208 $this->assertEquals($key2, $hashes[$index]); 2209 $index = array_search($key3, $hashes); 2210 $this->assertFalse($index); 2211 2212 // Check that the records have been removed as well. 2213 $records = $DB->get_records('h5p_libraries_cachedassets'); 2214 $this->assertCount(3, $records); 2215 } 2216 2217 /** 2218 * Test the behaviour of getLibraryContentCount(). 2219 */ 2220 public function test_getLibraryContentCount() { 2221 $this->resetAfterTest(); 2222 2223 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2224 2225 // Generate h5p related data. 2226 $data = $generator->generate_h5p_data(); 2227 2228 // The 'MainLibrary' library data. 2229 $mainlibrary = $data->mainlib->data; 2230 2231 // The 'Library2' library data. 2232 $library2 = $data->lib2->data; 2233 2234 // Create new h5p content with Library2 as it's main library. 2235 $generator->create_h5p_record($library2->id); 2236 2237 // Create new h5p content with MainLibrary as it's main library. 2238 $generator->create_h5p_record($mainlibrary->id); 2239 2240 $countlibrarycontent = $this->framework->getLibraryContentCount(); 2241 2242 $expected = array( 2243 "{$mainlibrary->machinename} {$mainlibrary->majorversion}.{$mainlibrary->minorversion}" => 2, 2244 "{$library2->machinename} {$library2->majorversion}.{$library2->minorversion}" => 1, 2245 ); 2246 2247 // MainLibrary and Library1 are currently main libraries to the existing h5p contents. 2248 // Should return the number of cases where MainLibrary and Library1 are main libraries to an h5p content. 2249 $this->assertEquals($expected, $countlibrarycontent); 2250 } 2251 2252 /** 2253 * Test the behaviour of test_libraryHasUpgrade(). 2254 * 2255 * @dataProvider libraryHasUpgrade_provider 2256 * @param array $libraryrecords Array containing data for the library creation 2257 * @param array $testlibrary Array containing the test library data 2258 * @param bool $expected The expectation whether the library is patched or not 2259 **/ 2260 public function test_libraryHasUpgrade(array $libraryrecords, array $testlibrary, bool $expected): void { 2261 $this->resetAfterTest(); 2262 2263 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2264 2265 foreach ($libraryrecords as $library) { 2266 call_user_func_array([$generator, 'create_library_record'], $library); 2267 } 2268 2269 $this->assertEquals($expected, $this->framework->libraryHasUpgrade($testlibrary)); 2270 } 2271 2272 /** 2273 * Data provider for test_libraryHasUpgrade(). 2274 * 2275 * @return array 2276 */ 2277 public function libraryHasUpgrade_provider(): array { 2278 return [ 2279 'Lower major version; Identical lower version' => [ 2280 [ 2281 ['Library', 'Lib', 2, 2], 2282 ], 2283 [ 2284 'machineName' => 'Library', 2285 'majorVersion' => 1, 2286 'minorVersion' => 2 2287 ], 2288 true, 2289 ], 2290 'Major version identical; Lower minor version' => [ 2291 [ 2292 ['Library', 'Lib', 2, 2], 2293 ], 2294 [ 2295 'machineName' => 'Library', 2296 'majorVersion' => 2, 2297 'minorVersion' => 1 2298 ], 2299 true, 2300 ], 2301 'Major version identical; Minor version identical' => [ 2302 [ 2303 ['Library', 'Lib', 2, 2], 2304 ], 2305 [ 2306 'machineName' => 'Library', 2307 'majorVersion' => 2, 2308 'minorVersion' => 2 2309 ], 2310 false, 2311 ], 2312 'Major version higher; Minor version identical' => [ 2313 [ 2314 ['Library', 'Lib', 2, 2], 2315 ], 2316 [ 2317 'machineName' => 'Library', 2318 'majorVersion' => 3, 2319 'minorVersion' => 2 2320 ], 2321 false, 2322 ], 2323 'Major version identical; Minor version newer' => [ 2324 [ 2325 ['Library', 'Lib', 2, 2], 2326 ], 2327 [ 2328 'machineName' => 'Library', 2329 'majorVersion' => 2, 2330 'minorVersion' => 4 2331 ], 2332 false, 2333 ] 2334 ]; 2335 } 2336 2337 2338 /** 2339 * Test the behaviour of get_latest_library_version(). 2340 */ 2341 public function test_get_latest_library_version() { 2342 global $DB; 2343 2344 $this->resetAfterTest(); 2345 2346 $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p'); 2347 // Create a library record. 2348 $machinename = 'TestLibrary'; 2349 $lib1 = $generator->create_library_record($machinename, 'Test', 1, 1, 2); 2350 $lib2 = $generator->create_library_record($machinename, 'Test', 1, 2, 1); 2351 2352 $content = array( 2353 'params' => json_encode(['param1' => 'Test']), 2354 'library' => array( 2355 'libraryId' => 0, 2356 'machineName' => 'TestLibrary', 2357 ), 2358 'disable' => 8 2359 ); 2360 2361 // Get the latest id (at this point, should be lib2). 2362 $latestlib = $this->framework->get_latest_library_version($machinename); 2363 $this->assertEquals($lib2->id, $latestlib->id); 2364 2365 // Get the latest id (at this point, should be lib3). 2366 $lib3 = $generator->create_library_record($machinename, 'Test', 2, 1, 0); 2367 $latestlib = $this->framework->get_latest_library_version($machinename); 2368 $this->assertEquals($lib3->id, $latestlib->id); 2369 2370 // Get the latest id (at this point, should be still lib3). 2371 $lib4 = $generator->create_library_record($machinename, 'Test', 1, 1, 3); 2372 $latestlib = $this->framework->get_latest_library_version($machinename); 2373 $this->assertEquals($lib3->id, $latestlib->id); 2374 2375 // Get the latest id (at this point, should be lib5). 2376 $lib5 = $generator->create_library_record($machinename, 'Test', 2, 1, 6); 2377 $latestlib = $this->framework->get_latest_library_version($machinename); 2378 $this->assertEquals($lib5->id, $latestlib->id); 2379 } 2380 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body