<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_h5p;
use core_collator;
use Moodle\H5PCore;
use Moodle\H5PDisplayOptionBehaviour;
// phpcs:disable moodle.NamingConventions.ValidFunctionName.LowercaseMethod
/**
*
* Test class covering the H5PFrameworkInterface interface implementation.
*
* @package core_h5p
* @category test
* @copyright 2019 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_h5p\framework
* @runTestsInSeparateProcesses
*/
class framework_test extends \advanced_testcase {
/** @var \core_h5p\framework */
private $framework;
/**
* Set up function for tests.
*/
public function setUp(): void {
$factory = new \core_h5p\factory();
$this->framework = $factory->get_framework();
}
/**
* Test the behaviour of getPlatformInfo().
*/
public function test_getPlatformInfo() {
global $CFG;
$platforminfo = $this->framework->getPlatformInfo();
$expected = array(
'name' => 'Moodle',
'version' => $CFG->version,
'h5pVersion' => $CFG->version
);
$this->assertEquals($expected, $platforminfo);
}
/**
* Test the behaviour of fetchExternalData() when the store path is not defined.
*
* This test is intensive and requires downloading content of an external file,
* therefore it might take longer time to execute.
* In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
*/
public function test_fetchExternalData_no_path_defined() {
if (!PHPUNIT_LONGTEST) {
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
}
$this->resetAfterTest();
$library = 'H5P.Accordion';
// Provide a valid URL to an external H5P content.
$url = $this->getExternalTestFileUrl('/'.$library.'.h5p');
// Test fetching an external H5P content without defining a path to where the file should be stored.
$data = $this->framework->fetchExternalData($url, null, true);
// The response should not be empty and return true if the file was successfully downloaded.
$this->assertNotEmpty($data);
$this->assertTrue($data);
$h5pfolderpath = $this->framework->getUploadedH5pFolderPath();
// The uploaded file should exist on the filesystem.
$this->assertTrue(file_exists($h5pfolderpath . '.h5p'));
}
/**
* Test the behaviour of fetchExternalData() when the store path is defined.
*
* This test is intensive and requires downloading content of an external file,
* therefore it might take longer time to execute.
* In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
*/
public function test_fetchExternalData_path_defined() {
global $CFG;
if (!PHPUNIT_LONGTEST) {
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
}
$this->resetAfterTest();
$library = 'H5P.Accordion';
// Provide a valid URL to an external H5P content.
$url = $this->getExternalTestFileUrl('/'.$library.'.h5p');
$h5pfolderpath = $CFG->tempdir . uniqid('/h5p-');
$data = $this->framework->fetchExternalData($url, null, true, $h5pfolderpath . '.h5p');
// The response should not be empty and return true if the content has been successfully saved to a file.
$this->assertNotEmpty($data);
$this->assertTrue($data);
// The uploaded file should exist on the filesystem.
$this->assertTrue(file_exists($h5pfolderpath . '.h5p'));
}
/**
* Test the behaviour of fetchExternalData() when the URL is pointing to an external file that is
* not an h5p content.
*
* This test is intensive and requires downloading content of an external file,
* therefore it might take longer time to execute.
* In order to execute this test PHPUNIT_LONGTEST should be set to true in phpunit.xml or directly in config.php.
*/
public function test_fetchExternalData_url_not_h5p() {
if (!PHPUNIT_LONGTEST) {
// This test is intensive and requires downloading the content of an external file.
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
}
$this->resetAfterTest();
// Provide an URL to an external file that is not an H5P content file.
$url = $this->getExternalTestFileUrl('/h5pcontenttypes.json');
$data = $this->framework->fetchExternalData($url, null, true);
// The response should not be empty and return true if the content has been successfully saved to a file.
$this->assertNotEmpty($data);
$this->assertTrue($data);
// The uploaded file should exist on the filesystem with it's original extension.
// NOTE: The file would be later validated by the H5P Validator.
$h5pfolderpath = $this->framework->getUploadedH5pFolderPath();
$this->assertTrue(file_exists($h5pfolderpath . '.json'));
}
/**
* Test the behaviour of fetchExternalData() when the URL is invalid.
*/
public function test_fetchExternalData_url_invalid() {
// Provide an invalid URL to an external file.
$url = "someprotocol://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
$data = $this->framework->fetchExternalData($url, null, true);
// The response should be empty.
$this->assertEmpty($data);
}
/**
* Test the behaviour of setLibraryTutorialUrl().
*/
public function test_setLibraryTutorialUrl() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create several libraries records.
$lib1 = $generator->create_library_record('Library1', 'Lib1', 1, 0, 1, '', null, 'http://tutorial1.org',
'http://example.org');
$lib2 = $generator->create_library_record('Library2', 'Lib2', 2, 0, 1, '', null, 'http://tutorial2.org');
$lib3 = $generator->create_library_record('Library3', 'Lib3', 3, 0);
// Check only lib1 tutorial URL is updated.
$url = 'https://newtutorial.cat';
$this->framework->setLibraryTutorialUrl($lib1->machinename, $url);
$libraries = $DB->get_records('h5p_libraries');
$this->assertEquals($libraries[$lib1->id]->tutorial, $url);
$this->assertNotEquals($libraries[$lib2->id]->tutorial, $url);
// Check lib1 tutorial URL is set to null.
$this->framework->setLibraryTutorialUrl($lib1->machinename, null);
$libraries = $DB->get_records('h5p_libraries');
$this->assertCount(3, $libraries);
$this->assertNull($libraries[$lib1->id]->tutorial);
// Check no tutorial URL is set if library name doesn't exist.
$this->framework->setLibraryTutorialUrl('Unexisting library', $url);
$libraries = $DB->get_records('h5p_libraries');
$this->assertCount(3, $libraries);
$this->assertNull($libraries[$lib1->id]->tutorial);
$this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org');
$this->assertNull($libraries[$lib3->id]->tutorial);
// Check tutorial is set as expected when it was null.
$this->framework->setLibraryTutorialUrl($lib3->machinename, $url);
$libraries = $DB->get_records('h5p_libraries');
$this->assertEquals($libraries[$lib3->id]->tutorial, $url);
$this->assertNull($libraries[$lib1->id]->tutorial);
$this->assertEquals($libraries[$lib2->id]->tutorial, 'http://tutorial2.org');
}
/**
* Test the behaviour of setErrorMessage().
*/
public function test_setErrorMessage() {
// Set an error message and an error code.
$message = "Error message";
$code = '404';
// Set an error message.
$this->framework->setErrorMessage($message, $code);
// Get the error messages.
$errormessages = $this->framework->getMessages('error');
$expected = new \stdClass();
$expected->code = 404;
$expected->message = 'Error message';
$this->assertEquals($expected, $errormessages[0]);
}
/**
* Test the behaviour of setInfoMessage().
*/
public function test_setInfoMessage() {
$message = "Info message";
// Set an info message.
$this->framework->setInfoMessage($message);
// Get the info messages.
$infomessages = $this->framework->getMessages('info');
$expected = 'Info message';
$this->assertEquals($expected, $infomessages[0]);
}
/**
* Test the behaviour of getMessages() when requesting the info messages.
*/
public function test_getMessages_info() {
// Set an info message.
$this->framework->setInfoMessage("Info message");
// Set an error message.
$this->framework->setErrorMessage("Error message 1", 404);
// Get the info messages.
$infomessages = $this->framework->getMessages('info');
$expected = 'Info message';
// Make sure that only the info message has been returned.
$this->assertCount(1, $infomessages);
$this->assertEquals($expected, $infomessages[0]);
$infomessages = $this->framework->getMessages('info');
// Make sure the info messages have now been removed.
$this->assertEmpty($infomessages);
}
/**
* Test the behaviour of getMessages() when requesting the error messages.
*/
public function test_getMessages_error() {
// Set an info message.
$this->framework->setInfoMessage("Info message");
// Set an error message.
$this->framework->setErrorMessage("Error message 1", 404);
// Set another error message.
$this->framework->setErrorMessage("Error message 2", 403);
// Get the error messages.
$errormessages = $this->framework->getMessages('error');
// Make sure that only the error messages are being returned.
$this->assertEquals(2, count($errormessages));
$expected1 = (object) [
'code' => 404,
'message' => 'Error message 1'
];
$expected2 = (object) [
'code' => 403,
'message' => 'Error message 2'
];
$this->assertEquals($expected1, $errormessages[0]);
$this->assertEquals($expected2, $errormessages[1]);
$errormessages = $this->framework->getMessages('error');
// Make sure the info messages have now been removed.
$this->assertEmpty($errormessages);
}
/**
* Test the behaviour of t() when translating existing string that does not require any arguments.
*/
public function test_t_existing_string_no_args() {
// Existing language string without passed arguments.
$translation = $this->framework->t('No copyright information available for this content.');
// Make sure the string translation has been returned.
$this->assertEquals('No copyright information available for this content.', $translation);
}
/**
* Test the behaviour of t() when translating existing string that does require parameters.
*/
public function test_t_existing_string_args() {
// Existing language string with passed arguments.
$translation = $this->framework->t('Illegal option %option in %library',
['%option' => 'example', '%library' => 'Test library']);
// Make sure the string translation has been returned.
$this->assertEquals('Illegal option example in Test library', $translation);
}
/**
* Test the behaviour of t() when translating non-existent string.
*/
public function test_t_non_existent_string() {
// Non-existing language string.
$message = 'Random message %option';
$translation = $this->framework->t($message);
// Make sure a debugging message is triggered.
$this->assertDebuggingCalled("String translation cannot be found. Please add a string definition for '" .
$message . "' in the core_h5p component.");
// As the string does not exist in the mapping array, make sure the passed message is returned.
$this->assertEquals($message, $translation);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and
* the folder name is parsable.
**/
public function test_getLibraryFileUrl() {
global $CFG;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$lib = $generator->create_library_record('Library', 'Lib', 1, 1);
$expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/library.json";
// Get the URL of a file from an existing library. The provided folder name is parsable.
$actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json');
// Make sure the expected URL is returned.
$this->assertEquals($expected, $actual);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from a non-existent library and
* the folder name is parsable.
**/
public function test_getLibraryFileUrl_non_existent_library() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$generator->create_library_record('Library', 'Lib', 1, 1);
// Get the URL of a file from a non-existent library. The provided folder name is parsable.
$actual = $this->framework->getLibraryFileUrl('Library2-1.1', 'library.json');
// Make sure a debugging message is triggered.
$this->assertDebuggingCalled('The library "Library2-1.1" does not exist.');
// Make sure that an URL is not returned.
$this->assertEquals(null, $actual);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from an existing library and
* the folder name is not parsable.
**/
public function test_getLibraryFileUrl_not_parsable_folder_name() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$generator->create_library_record('Library', 'Lib', 1, 1);
// Get the URL of a file from an existing library. The provided folder name is not parsable.
$actual = $this->framework->getLibraryFileUrl('Library1.1', 'library.json');
// Make sure a debugging message is triggered.
$this->assertDebuggingCalled(
'The provided string value "Library1.1" is not a valid name for a library folder.');
// Make sure that an URL is not returned.
$this->assertEquals(null, $actual);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple
* versions and the folder name is parsable.
**/
public function test_getLibraryFileUrl_library_has_multiple_versions() {
global $CFG;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create library records with a different minor version.
$lib1 = $generator->create_library_record('Library', 'Lib', 1, 1);
$lib2 = $generator->create_library_record('Library', 'Lib', 1, 3);
$expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.3/library.json";
// Get the URL of a file from an existing library (Library 1.3). The provided folder name is parsable.
$actual = $this->framework->getLibraryFileUrl('Library-1.3', 'library.json');
// Make sure the proper URL (from the requested library version) is returned.
$this->assertEquals($expected, $actual);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from a library that has multiple
* patch versions and the folder name is parsable.
**/
public function test_getLibraryFileUrl_library_has_multiple_patch_versions() {
global $CFG;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create library records with a different patch version.
$lib1 = $generator->create_library_record('Library', 'Lib', 1, 1, 2);
$lib2 = $generator->create_library_record('Library', 'Lib', 1, 1, 4);
$lib3 = $generator->create_library_record('Library', 'Lib', 1, 1, 3);
$expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib2->id}/Library-1.1/library.json";
// Get the URL of a file from an existing library. The provided folder name is parsable.
$actual = $this->framework->getLibraryFileUrl('Library-1.1', 'library.json');
// Make sure the proper URL (from the latest library patch) is returned.
$this->assertEquals($expected, $actual);
}
/**
* Test the behaviour of getLibraryFileUrl() when requesting a file URL from a sub-folder
* of an existing library and the folder name is parsable.
**/
public function test_getLibraryFileUrl_library_subfolder() {
global $CFG;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$lib = $generator->create_library_record('Library', 'Lib', 1, 1);
$expected = "{$CFG->wwwroot}/pluginfile.php/1/core_h5p/libraries/{$lib->id}/Library-1.1/css/example.css";
// Get the URL of a file from a sub-folder from an existing library. The provided folder name is parsable.
$actual = $this->framework->getLibraryFileUrl('Library-1.1/css', 'example.css');
// Make sure the proper URL is returned.
$this->assertEquals($expected, $actual);
}
/**
* Test the behaviour of loadAddons().
*/
public function test_loadAddons() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a Library addon (1.1).
$generator->create_library_record('Library', 'Lib', 1, 1, 2,
'', '/regex1/');
// Create a Library addon (1.3).
$generator->create_library_record('Library', 'Lib', 1, 3, 2,
'', '/regex2/');
// Create a Library addon (1.2).
$generator->create_library_record('Library', 'Lib', 1, 2, 2,
'', '/regex3/');
// Create a Library1 addon (1.2)
$generator->create_library_record('Library1', 'Lib1', 1, 2, 2,
'', '/regex11/');
// Load the latest version of each addon.
$addons = $this->framework->loadAddons();
// The addons array should return 2 results (Library and Library1 addon).
$this->assertCount(2, $addons);
// Ensure the addons array is consistently ordered before asserting their contents.
core_collator::asort_array_of_arrays_by_key($addons, 'machineName');
[$addonone, $addontwo] = array_values($addons);
// Make sure the version 1.3 is the latest 'Library' addon version.
$this->assertEquals('Library', $addonone['machineName']);
$this->assertEquals(1, $addonone['majorVersion']);
$this->assertEquals(3, $addonone['minorVersion']);
// Make sure the version 1.2 is the latest 'Library1' addon version.
$this->assertEquals('Library1', $addontwo['machineName']);
$this->assertEquals(1, $addontwo['majorVersion']);
$this->assertEquals(2, $addontwo['minorVersion']);
}
/**
* Test the behaviour of loadLibraries().
*/
public function test_loadLibraries() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$generator->generate_h5p_data();
// Load all libraries.
$libraries = $this->framework->loadLibraries();
// Make sure all libraries are returned.
$this->assertNotEmpty($libraries);
$this->assertCount(6, $libraries);
$this->assertEquals('MainLibrary', $libraries['MainLibrary'][0]->machine_name);
$this->assertEquals('1', $libraries['MainLibrary'][0]->major_version);
$this->assertEquals('0', $libraries['MainLibrary'][0]->minor_version);
$this->assertEquals('1', $libraries['MainLibrary'][0]->patch_version);
}
/**
* Test the behaviour of test_getLibraryId() when requesting an existing machine name.
*/
public function test_getLibraryId_existing_machine_name() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library.
$lib = $generator->create_library_record('Library', 'Lib', 1, 1, 2);
// Request the library ID of the library with machine name 'Library'.
$libraryid = $this->framework->getLibraryId('Library');
// Make sure the library ID is being returned.
$this->assertNotFalse($libraryid);
$this->assertEquals($lib->id, $libraryid);
}
/**
* Test the behaviour of test_getLibraryId() when requesting a non-existent machine name.
*/
public function test_getLibraryId_non_existent_machine_name() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library.
$generator->create_library_record('Library', 'Lib', 1, 1, 2);
// Request the library ID of the library with machinename => 'TestLibrary' (non-existent).
$libraryid = $this->framework->getLibraryId('TestLibrary');
// Make sure the library ID not being returned.
$this->assertFalse($libraryid);
}
/**
* Test the behaviour of test_getLibraryId() when requesting a non-existent major version.
*/
public function test_getLibraryId_non_existent_major_version() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library.
$generator->create_library_record('Library', 'Lib', 1, 1, 2);
// Request the library ID of the library with machine name => 'Library', majorversion => 2 (non-existent).
$libraryid = $this->framework->getLibraryId('Library', 2);
// Make sure the library ID not being returned.
$this->assertFalse($libraryid);
}
/**
* Test the behaviour of test_getLibraryId() when requesting a non-existent minor version.
*/
public function test_getLibraryId_non_existent_minor_version() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library.
$generator->create_library_record('Library', 'Lib', 1, 1, 2);
// Request the library ID of the library with machine name => 'Library',
// majorversion => 1, minorversion => 2 (non-existent).
$libraryid = $this->framework->getLibraryId('Library', 1, 2);
// Make sure the library ID not being returned.
$this->assertFalse($libraryid);
}
/**
* Test the behaviour of isPatchedLibrary().
*
* @dataProvider isPatchedLibrary_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param bool $expected The expectation whether the library is patched or not
**/
public function test_isPatchedLibrary(array $libraryrecords, array $testlibrary, bool $expected): void {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
foreach ($libraryrecords as $library) {
call_user_func_array([$generator, 'create_library_record'], $library);
}
$this->assertEquals($expected, $this->framework->isPatchedLibrary($testlibrary));
}
/**
* Data provider for test_isPatchedLibrary().
*
* @return array
*/
public function isPatchedLibrary_provider(): array {
return [
'Unpatched library. No different versioning' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 1,
'minorVersion' => 1,
'patchVersion' => 2
],
false,
],
'Major version identical; Minor version identical; Patch version newer' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 1,
'minorVersion' => 1,
'patchVersion' => 3
],
true,
],
'Major version identical; Minor version newer; Patch version newer' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 1,
'minorVersion' => 2,
'patchVersion' => 3
],
false,
],
'Major version identical; Minor version identical; Patch version older' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 1,
'minorVersion' => 1,
'patchVersion' => 1
],
false,
],
'Major version identical; Minor version newer; Patch version older' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 1,
'minorVersion' => 2,
'patchVersion' => 1
],
false,
],
'Major version newer; Minor version identical; Patch version older' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 2,
'minorVersion' => 1,
'patchVersion' => 1
],
false,
],
'Major version newer; Minor version identical; Patch version newer' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 2,
'minorVersion' => 1,
'patchVersion' => 3
],
false,
],
'Major version older; Minor version identical; Patch version older' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 0,
'minorVersion' => 1,
'patchVersion' => 1
],
false,
],
'Major version older; Minor version identical; Patch version newer' => [
[
['TestLibrary', 'Test', 1, 1, 2],
],
[
'machineName' => 'TestLibrary',
'majorVersion' => 0,
'minorVersion' => 1,
'patchVersion' => 3
],
false,
],
];
}
/**
* Test the behaviour of isInDevMode().
*/
public function test_isInDevMode() {
$isdevmode = $this->framework->isInDevMode();
$this->assertFalse($isdevmode);
}
/**
* Test the behaviour of mayUpdateLibraries().
*/
public function test_mayUpdateLibraries(): void {
global $DB;
$this->resetAfterTest();
// Create some users.
$contextsys = \context_system::instance();
$user = $this->getDataGenerator()->create_user();
$admin = get_admin();
$managerrole = $DB->get_record('role', ['shortname' => 'manager'], '*', MUST_EXIST);
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
$manager = $this->getDataGenerator()->create_user();
role_assign($managerrole->id, $manager->id, $contextsys);
// Create a course with a label and enrol the user.
$course = $this->getDataGenerator()->create_course();
$label = $this->getDataGenerator()->create_module('label', ['course' => $course->id]);
list(, $labelcm) = get_course_and_cm_from_instance($label->id, 'label');
$contextlabel = \context_module::instance($labelcm->id);
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
// Create the .h5p file.
$path = __DIR__ . '/fixtures/h5ptest.zip';
// Admin and manager should have permission to update libraries.
$file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextsys);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertTrue($mayupdatelib);
$file = helper::create_fake_stored_file_from_path($path, $manager->id, $contextsys);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertTrue($mayupdatelib);
// By default, normal user hasn't permission to update libraries (in both contexts, system and module label).
$file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertFalse($mayupdatelib);
$file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertFalse($mayupdatelib);
// If the current user (admin) can update libraries, the method should return true (even if the file userid hasn't the
// required capabilility in the file context).
$file = helper::create_fake_stored_file_from_path($path, $admin->id, $contextlabel);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertTrue($mayupdatelib);
// If the update capability is assigned to the user, they should be able to update the libraries (only in the context
// where the capability has been assigned).
$file = helper::create_fake_stored_file_from_path($path, $user->id, $contextlabel);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertFalse($mayupdatelib);
assign_capability('moodle/h5p:updatelibraries', CAP_ALLOW, $studentrole->id, $contextlabel);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertTrue($mayupdatelib);
$file = helper::create_fake_stored_file_from_path($path, $user->id, $contextsys);
$this->framework->set_file($file);
$mayupdatelib = $this->framework->mayUpdateLibraries();
$this->assertFalse($mayupdatelib);
}
/**
* Test the behaviour of get_file() and set_file().
*/
public function test_get_file(): void {
$this->resetAfterTest();
// Create some users.
$contextsys = \context_system::instance();
$user = $this->getDataGenerator()->create_user();
// The H5P file.
$path = __DIR__ . '/fixtures/h5ptest.zip';
// An error should be raised when it's called before initialitzing it.
$this->expectException('coding_exception');
$this->expectExceptionMessage('Using get_file() before file is set');
$this->framework->get_file();
// Check the value when only path and user are set.
$file = helper::create_fake_stored_file_from_path($path, $user->id);
$this->framework->set_file($file);
$file = $this->framework->get_file();
$this->assertEquals($user->id, $$file->get_userid());
$this->assertEquals($contextsys->id, $file->get_contextid());
// Check the value when also the context is set.
$course = $this->getDataGenerator()->create_course();
$contextcourse = \context_course::instance($course->id);
$file = helper::create_fake_stored_file_from_path($path, $user->id, $contextcourse);
$this->framework->set_file($file);
$file = $this->framework->get_file();
$this->assertEquals($user->id, $$file->get_userid());
$this->assertEquals($contextcourse->id, $file->get_contextid());
}
/**
* Test the behaviour of saveLibraryData() when saving data for a new library.
*/
public function test_saveLibraryData_new_library() {
global $DB;
$this->resetAfterTest();
$librarydata = array(
'title' => 'Test',
'machineName' => 'TestLibrary',
'majorVersion' => '1',
'minorVersion' => '0',
'patchVersion' => '2',
'runnable' => 1,
'fullscreen' => 1,
'preloadedJs' => array(
array(
'path' => 'js/name.min.js'
)
),
'preloadedCss' => array(
array(
'path' => 'css/name.css'
)
),
'dropLibraryCss' => array(
array(
'machineName' => 'Name2'
)
)
);
// Create a new library.
$this->framework->saveLibraryData($librarydata);
$library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]);
// Make sure the library data was properly saved.
$this->assertNotEmpty($library);
$this->assertNotEmpty($librarydata['libraryId']);
$this->assertEquals($librarydata['title'], $library->title);
$this->assertEquals($librarydata['machineName'], $library->machinename);
$this->assertEquals($librarydata['majorVersion'], $library->majorversion);
$this->assertEquals($librarydata['minorVersion'], $library->minorversion);
$this->assertEquals($librarydata['patchVersion'], $library->patchversion);
$this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs);
$this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss);
$this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss);
}
/**
* Test the behaviour of saveLibraryData() when saving (updating) data for an existing library.
*/
public function test_saveLibraryData_existing_library() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$library = $generator->create_library_record('TestLibrary', 'Test', 1, 0, 2);
$librarydata = array(
'libraryId' => $library->id,
'title' => 'Test1',
'machineName' => 'TestLibrary',
'majorVersion' => '1',
'minorVersion' => '2',
'patchVersion' => '2',
'runnable' => 1,
'fullscreen' => 1,
'preloadedJs' => array(
array(
'path' => 'js/name.min.js'
)
),
'preloadedCss' => array(
array(
'path' => 'css/name.css'
)
),
'dropLibraryCss' => array(
array(
'machineName' => 'Name2'
)
)
);
// Update the library.
$this->framework->saveLibraryData($librarydata, false);
$library = $DB->get_record('h5p_libraries', ['machinename' => $librarydata['machineName']]);
// Make sure the library data was properly updated.
$this->assertNotEmpty($library);
$this->assertNotEmpty($librarydata['libraryId']);
$this->assertEquals($librarydata['title'], $library->title);
$this->assertEquals($librarydata['machineName'], $library->machinename);
$this->assertEquals($librarydata['majorVersion'], $library->majorversion);
$this->assertEquals($librarydata['minorVersion'], $library->minorversion);
$this->assertEquals($librarydata['patchVersion'], $library->patchversion);
$this->assertEquals($librarydata['preloadedJs'][0]['path'], $library->preloadedjs);
$this->assertEquals($librarydata['preloadedCss'][0]['path'], $library->preloadedcss);
$this->assertEquals($librarydata['dropLibraryCss'][0]['machineName'], $library->droplibrarycss);
}
/**
* Test the behaviour of insertContent().
*/
public function test_insertContent() {
global $DB;
$this->resetAfterTest();
$content = array(
'params' => json_encode(['param1' => 'Test']),
'library' => array(
'libraryId' => 1
),
'disable' => 8
);
// Insert h5p content.
$contentid = $this->framework->insertContent($content);
// Get the entered content from the db.
$dbcontent = $DB->get_record('h5p', ['id' => $contentid]);
// Make sure the h5p content was properly inserted.
$this->assertNotEmpty($dbcontent);
$this->assertEquals($content['params'], $dbcontent->jsoncontent);
$this->assertEquals($content['library']['libraryId'], $dbcontent->mainlibraryid);
$this->assertEquals($content['disable'], $dbcontent->displayoptions);
}
/**
* Test the behaviour of insertContent().
*/
public function test_insertContent_latestlibrary() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
$content = array(
'params' => json_encode(['param1' => 'Test']),
'library' => array(
'libraryId' => 0,
'machineName' => 'TestLibrary',
),
'disable' => 8
);
// Insert h5p content.
$contentid = $this->framework->insertContent($content);
// Get the entered content from the db.
$dbcontent = $DB->get_record('h5p', ['id' => $contentid]);
// Make sure the h5p content was properly inserted.
$this->assertNotEmpty($dbcontent);
$this->assertEquals($content['params'], $dbcontent->jsoncontent);
$this->assertEquals($content['disable'], $dbcontent->displayoptions);
// As the libraryId was empty, the latest library has been used.
$this->assertEquals($lib->id, $dbcontent->mainlibraryid);
}
/**
* Test the behaviour of updateContent().
*/
public function test_updateContent() {
global $DB;
$this->resetAfterTest();
> /** @var \core_h5p_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
// Create an h5p content with 'TestLibrary' as it's main library.
$contentid = $generator->create_h5p_record($lib->id);
$content = array(
'id' => $contentid,
'params' => json_encode(['param2' => 'Test2']),
'library' => array(
'libraryId' => $lib->id
),
'disable' => 8
);
// Update the h5p content.
$this->framework->updateContent($content);
$h5pcontent = $DB->get_record('h5p', ['id' => $contentid]);
// Make sure the h5p content was properly updated.
$this->assertNotEmpty($h5pcontent);
> $this->assertNotEmpty($h5pcontent->pathnamehash);
$this->assertEquals($content['params'], $h5pcontent->jsoncontent);
> $this->assertNotEmpty($h5pcontent->contenthash);
$this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid);
$this->assertEquals($content['disable'], $h5pcontent->displayoptions);
}
/**
* Test the behaviour of updateContent() with metadata.
*
* @covers ::updateContent
*/
public function test_updateContent_withmetadata(): void {
global $DB;
$this->resetAfterTest();
/** @var \core_h5p_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$lib = $generator->create_library_record('TestLibrary', 'Test', 1, 1, 2);
// Create an h5p content with 'TestLibrary' as it's main library.
$contentid = $generator->create_h5p_record($lib->id);
$params = ['param2' => 'Test2'];
$metadata = [
'license' => 'CC BY',
'licenseVersion' => '4.0',
'yearFrom' => 2000,
'yearTo' => 2023,
'defaultLanguage' => 'ca',
];
$content = [
'id' => $contentid,
'params' => json_encode($params),
'library' => [
'libraryId' => $lib->id,
],
'disable' => 8,
'metadata' => $metadata,
];
// Update the h5p content.
$this->framework->updateContent($content);
$h5pcontent = $DB->get_record('h5p', ['id' => $contentid]);
// Make sure the h5p content was properly updated.
$this->assertNotEmpty($h5pcontent);
> $this->assertNotEmpty($h5pcontent->pathnamehash);
$this->assertEquals(json_encode(array_merge($params, ['metadata' => $metadata])), $h5pcontent->jsoncontent);
> $this->assertNotEmpty($h5pcontent->contenthash);
$this->assertEquals($content['library']['libraryId'], $h5pcontent->mainlibraryid);
$this->assertEquals($content['disable'], $h5pcontent->displayoptions);
}
/**
* Test the behaviour of saveLibraryDependencies().
*/
public function test_saveLibraryDependencies() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library 'Library'.
$library = $generator->create_library_record('Library', 'Title');
// Create a library 'DependencyLibrary1'.
$dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1');
// Create a library 'DependencyLibrary2'.
$dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2');
$dependencies = array(
array(
'machineName' => $dependency1->machinename,
'majorVersion' => $dependency1->majorversion,
'minorVersion' => $dependency1->minorversion
),
array(
'machineName' => $dependency2->machinename,
'majorVersion' => $dependency2->majorversion,
'minorVersion' => $dependency2->minorversion
),
);
// Set 'DependencyLibrary1' and 'DependencyLibrary2' as library dependencies of 'Library'.
$this->framework->saveLibraryDependencies($library->id, $dependencies, 'preloaded');
$libdependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library->id], 'id ASC');
// Make sure the library dependencies for 'Library' are properly set.
$this->assertEquals(2, count($libdependencies));
$this->assertEquals($dependency1->id, reset($libdependencies)->requiredlibraryid);
$this->assertEquals($dependency2->id, end($libdependencies)->requiredlibraryid);
}
/**
* Test the behaviour of deleteContentData().
*/
public function test_deleteContentData() {
global $DB;
$this->resetAfterTest();
> /** @var \core_h5p_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
> // For the mod_h5pactivity component, the activity needs to be created too.
> $course = $this->getDataGenerator()->create_course();
// Generate some h5p related data.
> $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
$data = $generator->generate_h5p_data();
> $this->setUser($user);
$h5pid = $data->h5pcontent->h5pid;
> $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
> $activitycontext = \context_module::instance($activity->cmid);
$h5pcontent = $DB->get_record('h5p', ['id' => $h5pid]);
> $filerecord = [
// Make sure the particular h5p content exists in the DB.
> 'contextid' => $activitycontext->id,
$this->assertNotEmpty($h5pcontent);
> 'component' => 'mod_h5pactivity',
> 'filearea' => 'package',
// Get the h5p content libraries from the DB.
> 'itemid' => 0,
$h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]);
> 'filepath' => '/',
> 'filename' => 'dummy.h5p',
// Make sure the content libraries exists in the DB.
> 'addxapistate' => true,
$this->assertNotEmpty($h5pcontentlibraries);
> ];
< $data = $generator->generate_h5p_data();
> $data = $generator->generate_h5p_data(false, $filerecord);
< $h5pcontent = $DB->get_record('h5p', ['id' => $h5pid]);
< $this->assertNotEmpty($h5pcontent);
<
< // Get the h5p content libraries from the DB.
< $h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]);
<
> $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
< $this->assertNotEmpty($h5pcontentlibraries);
< $this->assertCount(5, $h5pcontentlibraries);
> $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
> // Make sure the particular xAPI state exists in the DB.
> $records = $DB->get_records('xapi_states');
> $record = reset($records);
> $this->assertCount(1, $records);
> $this->assertNotNull($record->statedata);
< $h5pcontent = $DB->get_record('h5p', ['id' => $h5pid]);
< $h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]);
<
< $this->assertEmpty($h5pcontent);
> $this->assertEmpty($DB->get_record('h5p', ['id' => $h5pid]));
< $this->assertEmpty($h5pcontentlibraries);
> $this->assertEmpty($DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]));
> // The xAPI state should be reseted.
> $records = $DB->get_records('xapi_states');
> $record = reset($records);
> $this->assertCount(1, $records);
> $this->assertNull($record->statedata);
> }
>
> /**
> * Test the behaviour of resetContentUserData().
> */
> public function test_resetContentUserData() {
> global $DB;
>
> $this->resetAfterTest();
>
> /** @var \core_h5p_generator $generator */
> $generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
> // For the mod_h5pactivity component, the activity needs to be created too.
> $course = $this->getDataGenerator()->create_course();
> $user = $this->getDataGenerator()->create_and_enrol($course, 'student');
> $this->setUser($user);
> $activity = $this->getDataGenerator()->create_module('h5pactivity', ['course' => $course]);
> $activitycontext = \context_module::instance($activity->cmid);
> $filerecord = [
> 'contextid' => $activitycontext->id,
> 'component' => 'mod_h5pactivity',
> 'filearea' => 'package',
> 'itemid' => 0,
> 'filepath' => '/',
> 'filename' => 'dummy.h5p',
> 'addxapistate' => true,
> ];
>
> // Generate some h5p related data.
> $data = $generator->generate_h5p_data(false, $filerecord);
> $h5pid = $data->h5pcontent->h5pid;
>
> // Make sure the H5P content, libraries and xAPI state exist in the DB.
> $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
> $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
> $records = $DB->get_records('xapi_states');
> $record = reset($records);
> $this->assertCount(1, $records);
> $this->assertNotNull($record->statedata);
>
> // Reset the user data associated to this H5P content.
> $this->framework->resetContentUserData($h5pid);
>
> // The H5P content should still exist in the db.
> $this->assertNotEmpty($DB->get_record('h5p', ['id' => $h5pid]));
> // The particular content libraries should still exist in the db.
> $this->assertCount(5, $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]));
> // The xAPI state should still exist in the db, but should be reset.
> $records = $DB->get_records('xapi_states');
> $record = reset($records);
> $this->assertCount(1, $records);
> $this->assertNull($record->statedata);
/**
* Test the behaviour of deleteLibraryUsage().
*/
public function test_deleteLibraryUsage() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate some h5p related data.
$data = $generator->generate_h5p_data();
$h5pid = $data->h5pcontent->h5pid;
// Get the h5p content libraries from the DB.
$h5pcontentlibraries = $DB->get_records('h5p_contents_libraries', ['h5pid' => $h5pid]);
// The particular h5p content should have 5 content libraries.
$this->assertNotEmpty($h5pcontentlibraries);
$this->assertCount(5, $h5pcontentlibraries);
// Delete the h5p content and it's related data.
$this->framework->deleteLibraryUsage($h5pid);
// Get the h5p content libraries from the DB.
$h5pcontentlibraries = $DB->get_record('h5p_contents_libraries', ['h5pid' => $h5pid]);
// The particular h5p content libraries should no longer exist in the db.
$this->assertEmpty($h5pcontentlibraries);
}
/**
* Test the behaviour of test_saveLibraryUsage().
*/
public function test_saveLibraryUsage() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library 'Library'.
$library = $generator->create_library_record('Library', 'Title');
// Create a library 'DependencyLibrary1'.
$dependency1 = $generator->create_library_record('DependencyLibrary1', 'DependencyTitle1');
// Create a library 'DependencyLibrary2'.
$dependency2 = $generator->create_library_record('DependencyLibrary2', 'DependencyTitle2');
// Create an h5p content with 'Library' as it's main library.
$contentid = $generator->create_h5p_record($library->id);
$dependencies = array(
array(
'library' => array(
'libraryId' => $dependency1->id,
'machineName' => $dependency1->machinename,
'dropLibraryCss' => $dependency1->droplibrarycss
),
'type' => 'preloaded',
'weight' => 1
),
array(
'library' => array(
'libraryId' => $dependency2->id,
'machineName' => $dependency2->machinename,
'dropLibraryCss' => $dependency2->droplibrarycss
),
'type' => 'preloaded',
'weight' => 2
),
);
// Save 'DependencyLibrary1' and 'DependencyLibrary2' as h5p content libraries.
$this->framework->saveLibraryUsage($contentid, $dependencies);
// Get the h5p content libraries from the DB.
$libdependencies = $DB->get_records('h5p_contents_libraries', ['h5pid' => $contentid], 'id ASC');
// Make sure that 'DependencyLibrary1' and 'DependencyLibrary2' are properly set as h5p content libraries.
$this->assertEquals(2, count($libdependencies));
$this->assertEquals($dependency1->id, reset($libdependencies)->libraryid);
$this->assertEquals($dependency2->id, end($libdependencies)->libraryid);
}
/**
* Test the behaviour of getLibraryUsage() without skipping a particular h5p content.
*/
public function test_getLibraryUsage_no_skip_content() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$generateddata = $generator->generate_h5p_data();
// The Id of the library 'Library1'.
$library1id = $generateddata->lib1->data->id;
// The Id of the library 'Library2'.
$library2id = $generateddata->lib2->data->id;
// The Id of the library 'Library5'.
$library5id = $generateddata->lib5->data->id;
// Get the library usage for 'Library1' (do not skip content).
$data = $this->framework->getLibraryUsage($library1id);
$expected = array(
'content' => 1,
'libraries' => 1
);
// Make sure 'Library1' is used by 1 content and is a dependency to 1 library.
$this->assertEquals($expected, $data);
// Get the library usage for 'Library2' (do not skip content).
$data = $this->framework->getLibraryUsage($library2id);
$expected = array(
'content' => 1,
'libraries' => 2,
);
// Make sure 'Library2' is used by 1 content and is a dependency to 2 libraries.
$this->assertEquals($expected, $data);
// Get the library usage for 'Library5' (do not skip content).
$data = $this->framework->getLibraryUsage($library5id);
$expected = array(
'content' => 0,
'libraries' => 1,
);
// Make sure 'Library5' is not used by any content and is a dependency to 1 library.
$this->assertEquals($expected, $data);
}
/**
* Test the behaviour of getLibraryUsage() when skipping a particular content.
*/
public function test_getLibraryUsage_skip_content() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$generateddata = $generator->generate_h5p_data();
// The Id of the library 'Library1'.
$library1id = $generateddata->lib1->data->id;
// Get the library usage for 'Library1' (skip content).
$data = $this->framework->getLibraryUsage($library1id, true);
$expected = array(
'content' => -1,
'libraries' => 1,
);
// Make sure 'Library1' is a dependency to 1 library.
$this->assertEquals($expected, $data);
}
/**
* Test the behaviour of loadLibrary() when requesting an existing library.
*/
public function test_loadLibrary_existing_library() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$generateddata = $generator->generate_h5p_data();
// The library data of 'Library1'.
$library1 = $generateddata->lib1->data;
// The library data of 'Library5'.
$library5 = $generateddata->lib5->data;
// The preloaded dependencies.
$preloadeddependencies = array();
foreach ($generateddata->lib1->dependencies as $preloadeddependency) {
$preloadeddependencies[] = array(
'machineName' => $preloadeddependency->machinename,
'majorVersion' => $preloadeddependency->majorversion,
'minorVersion' => $preloadeddependency->minorversion
);
}
// Create a dynamic dependency.
$generator->create_library_dependency_record($library1->id, $library5->id, 'dynamic');
$dynamicdependencies[] = array(
'machineName' => $library5->machinename,
'majorVersion' => $library5->majorversion,
'minorVersion' => $library5->minorversion
);
// Load 'Library1' data.
$data = $this->framework->loadLibrary($library1->machinename, $library1->majorversion,
$library1->minorversion);
$expected = array(
'libraryId' => $library1->id,
'title' => $library1->title,
'machineName' => $library1->machinename,
'majorVersion' => $library1->majorversion,
'minorVersion' => $library1->minorversion,
'patchVersion' => $library1->patchversion,
'runnable' => $library1->runnable,
'fullscreen' => $library1->fullscreen,
'embedTypes' => $library1->embedtypes,
'preloadedJs' => $library1->preloadedjs,
'preloadedCss' => $library1->preloadedcss,
'dropLibraryCss' => $library1->droplibrarycss,
'semantics' => $library1->semantics,
'preloadedDependencies' => $preloadeddependencies,
'dynamicDependencies' => $dynamicdependencies
);
// Make sure the 'Library1' data is properly loaded.
$this->assertEquals($expected, $data);
}
/**
* Test the behaviour of loadLibrary() when requesting a non-existent library.
*/
public function test_loadLibrary_non_existent_library() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$generator->generate_h5p_data();
// Attempt to load a non-existent library.
$data = $this->framework->loadLibrary('MissingLibrary', 1, 2);
// Make sure nothing is loaded.
$this->assertFalse($data);
}
/**
* Test the behaviour of loadLibrarySemantics().
*
* @dataProvider loadLibrarySemantics_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param string $expected The expected semantics value
**/
public function test_loadLibrarySemantics(array $libraryrecords, array $testlibrary, string $expected): void {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
foreach ($libraryrecords as $library) {
call_user_func_array([$generator, 'create_library_record'], $library);
}
$this->assertEquals($expected, $this->framework->loadLibrarySemantics(
$testlibrary['machinename'], $testlibrary['majorversion'], $testlibrary['minorversion']));
}
/**
* Data provider for test_loadLibrarySemantics().
*
* @return array
*/
public function loadLibrarySemantics_provider(): array {
$semantics = json_encode(
[
'type' => 'text',
'name' => 'text',
'label' => 'Plain text',
'description' => 'Please add some text'
]
);
return [
'Library with semantics' => [
[
['Library1', 'Lib1', 1, 1, 2, $semantics],
],
[
'machinename' => 'Library1',
'majorversion' => 1,
'minorversion' => 1
],
$semantics,
],
'Library without semantics' => [
[
['Library2', 'Lib2', 1, 2, 2, ''],
],
[
'machinename' => 'Library2',
'majorversion' => 1,
'minorversion' => 2
],
'',
]
];
}
/**
* Test the behaviour of alterLibrarySemantics().
*/
public function test_alterLibrarySemantics() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
$semantics = json_encode(
array(
'type' => 'text',
'name' => 'text',
'label' => 'Plain text',
'description' => 'Please add some text'
)
);
// Create a library 'Library1' with semantics.
$library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2, $semantics);
$updatedsemantics = array(
'type' => 'text',
'name' => 'updated text',
'label' => 'Updated text',
'description' => 'Please add some text'
);
// Alter the semantics of 'Library1'.
$this->framework->alterLibrarySemantics($updatedsemantics, 'Library1', 1, 1);
// Get the semantics of 'Library1' from the DB.
$currentsemantics = $DB->get_field('h5p_libraries', 'semantics', array('id' => $library1->id));
// The semantics for Library1 shouldn't be updated.
$this->assertEquals($semantics, $currentsemantics);
}
/**
* Test the behaviour of deleteLibraryDependencies() when requesting to delete the
* dependencies of an existing library.
*/
public function test_deleteLibraryDependencies_existing_library() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The data of the library 'Library1'.
$library1 = $data->lib1->data;
// Get the dependencies of 'Library1'.
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
// The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4').
$this->assertCount(3, $dependencies);
// Delete the dependencies of 'Library1'.
$this->framework->deleteLibraryDependencies($library1->id);
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
// The 'Library1' should have 0 dependencies.
$this->assertCount(0, $dependencies);
}
/**
* Test the behaviour of deleteLibraryDependencies() when requesting to delete the
* dependencies of a non-existent library.
*/
public function test_deleteLibraryDependencies_non_existent_library() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The data of the library 'Library1'.
$library1 = $data->lib1->data;
// Get the dependencies of 'Library1'.
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
// The 'Library1' should have 3 dependencies ('Library2', 'Library3', 'Library4').
$this->assertCount(3, $dependencies);
// Delete the dependencies of a non-existent library.
$this->framework->deleteLibraryDependencies(0);
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
// The 'Library1' should have 3 dependencies.
$this->assertCount(3, $dependencies);
}
/**
* Test the behaviour of deleteLibrary().
*/
public function test_deleteLibrary() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data(true);
// The data of the 'Library1' library.
$library1 = $data->lib1->data;
// Get the library dependencies of 'Library1'.
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
// The 'Library1' should have 3 library dependencies ('Library2', 'Library3', 'Library4').
$this->assertCount(3, $dependencies);
// Return the created 'Library1' files.
$libraryfiles = $DB->get_records('files',
array(
'component' => \core_h5p\file_storage::COMPONENT,
'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA,
'itemid' => $library1->id
)
);
// The library ('Library1') should have 7 related folders/files.
$this->assertCount(7, $libraryfiles);
// Delete the library.
$this->framework->deleteLibrary($library1);
$lib1 = $DB->get_record('h5p_libraries', ['machinename' => $library1->machinename]);
$dependencies = $DB->get_records('h5p_library_dependencies', ['libraryid' => $library1->id]);
$libraryfiles = $DB->get_records('files',
array(
'component' => \core_h5p\file_storage::COMPONENT,
'filearea' => \core_h5p\file_storage::LIBRARY_FILEAREA,
'itemid' => $library1->id
)
);
// The 'Library1' should not exist.
$this->assertEmpty($lib1);
// The library ('Library1') should have 0 dependencies.
$this->assertCount(0, $dependencies);
// The library (library1) should have 0 related folders/files.
$this->assertCount(0, $libraryfiles);
}
/**
* Test the behaviour of loadContent().
*/
public function test_loadContent() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The Id of the created h5p content.
$h5pid = $data->h5pcontent->h5pid;
// Get the h5p content data from the DB.
$h5p = $DB->get_record('h5p', ['id' => $h5pid]);
// The data of content's main library ('MainLibrary').
$mainlibrary = $data->mainlib->data;
// Load the h5p content.
$content = $this->framework->loadContent($h5pid);
$expected = array(
'id' => $h5p->id,
'params' => $h5p->jsoncontent,
'embedType' => 'iframe',
'disable' => $h5p->displayoptions,
'title' => $mainlibrary->title,
'slug' => H5PCore::slugify($mainlibrary->title) . '-' . $h5p->id,
'filtered' => $h5p->filtered,
'libraryId' => $mainlibrary->id,
'libraryName' => $mainlibrary->machinename,
'libraryMajorVersion' => $mainlibrary->majorversion,
'libraryMinorVersion' => $mainlibrary->minorversion,
'libraryEmbedTypes' => $mainlibrary->embedtypes,
'libraryFullscreen' => $mainlibrary->fullscreen,
'metadata' => '',
'pathnamehash' => $h5p->pathnamehash
);
$params = json_decode($h5p->jsoncontent);
if (empty($params->metadata)) {
$params->metadata = new \stdClass();
}
$expected['metadata'] = $params->metadata;
$expected['params'] = json_encode($params->params ?? $params);
// The returned content should match the expected array.
$this->assertEquals($expected, $content);
}
/**
* Test the behaviour of loadContentDependencies() when requesting content dependencies
* without specifying the dependency type.
*/
public function test_loadContentDependencies_no_type_defined() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The Id of the h5p content.
$h5pid = $data->h5pcontent->h5pid;
// The content dependencies.
$dependencies = $data->h5pcontent->contentdependencies;
// Add Library5 as a content dependency (dynamic dependency type).
$library5 = $data->lib5->data;
$generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic');
// Get all content dependencies.
$contentdependencies = $this->framework->loadContentDependencies($h5pid);
$expected = array();
foreach ($dependencies as $dependency) {
$expected[$dependency->machinename] = array(
'libraryId' => $dependency->id,
'machineName' => $dependency->machinename,
'majorVersion' => $dependency->majorversion,
'minorVersion' => $dependency->minorversion,
'patchVersion' => $dependency->patchversion,
'preloadedCss' => $dependency->preloadedcss,
'preloadedJs' => $dependency->preloadedjs,
'dropCss' => '0',
'dependencyType' => 'preloaded'
);
}
$expected = array_merge($expected,
array(
'Library5' => array(
'libraryId' => $library5->id,
'machineName' => $library5->machinename,
'majorVersion' => $library5->majorversion,
'minorVersion' => $library5->minorversion,
'patchVersion' => $library5->patchversion,
'preloadedCss' => $library5->preloadedcss,
'preloadedJs' => $library5->preloadedjs,
'dropCss' => '0',
'dependencyType' => 'dynamic'
)
)
);
// The loaded content dependencies should return 6 libraries.
$this->assertCount(6, $contentdependencies);
$this->assertEquals($expected, $contentdependencies);
}
/**
* Test the behaviour of loadContentDependencies() when requesting content dependencies
* with specifying the dependency type.
*/
public function test_loadContentDependencies_type_defined() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The Id of the h5p content.
$h5pid = $data->h5pcontent->h5pid;
// The content dependencies.
$dependencies = $data->h5pcontent->contentdependencies;
// Add Library5 as a content dependency (dynamic dependency type).
$library5 = $data->lib5->data;
$generator->create_contents_libraries_record($h5pid, $library5->id, 'dynamic');
// Load all content dependencies of dependency type 'preloaded'.
$preloadeddependencies = $this->framework->loadContentDependencies($h5pid, 'preloaded');
$expected = array();
foreach ($dependencies as $dependency) {
$expected[$dependency->machinename] = array(
'libraryId' => $dependency->id,
'machineName' => $dependency->machinename,
'majorVersion' => $dependency->majorversion,
'minorVersion' => $dependency->minorversion,
'patchVersion' => $dependency->patchversion,
'preloadedCss' => $dependency->preloadedcss,
'preloadedJs' => $dependency->preloadedjs,
'dropCss' => '0',
'dependencyType' => 'preloaded'
);
}
// The loaded content dependencies should return 5 libraries.
$this->assertCount(5, $preloadeddependencies);
$this->assertEquals($expected, $preloadeddependencies);
// Load all content dependencies of dependency type 'dynamic'.
$dynamicdependencies = $this->framework->loadContentDependencies($h5pid, 'dynamic');
$expected = array(
'Library5' => array(
'libraryId' => $library5->id,
'machineName' => $library5->machinename,
'majorVersion' => $library5->majorversion,
'minorVersion' => $library5->minorversion,
'patchVersion' => $library5->patchversion,
'preloadedCss' => $library5->preloadedcss,
'preloadedJs' => $library5->preloadedjs,
'dropCss' => '0',
'dependencyType' => 'dynamic'
)
);
// The loaded content dependencies should now return 1 library.
$this->assertCount(1, $dynamicdependencies);
$this->assertEquals($expected, $dynamicdependencies);
}
/**
* Test the behaviour of getOption().
*/
public function test_getOption(): void {
$this->resetAfterTest();
// Get value for display_option_download.
$value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_DOWNLOAD);
$expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
$this->assertEquals($expected, $value);
// Get value for display_option_embed using default value (it should be ignored).
$value = $this->framework->getOption(H5PCore::DISPLAY_OPTION_EMBED, H5PDisplayOptionBehaviour::NEVER_SHOW);
$expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
$this->assertEquals($expected, $value);
// Get value for unexisting setting without default.
$value = $this->framework->getOption('unexistingsetting');
$expected = false;
$this->assertEquals($expected, $value);
// Get value for unexisting setting with default.
$value = $this->framework->getOption('unexistingsetting', 'defaultvalue');
$expected = 'defaultvalue';
$this->assertEquals($expected, $value);
}
/**
* Test the behaviour of setOption().
*/
public function test_setOption(): void {
$this->resetAfterTest();
// Set value for 'newsetting' setting.
$name = 'newsetting';
$value = $this->framework->getOption($name);
$this->assertEquals(false, $value);
$newvalue = 'value1';
$this->framework->setOption($name, $newvalue);
$value = $this->framework->getOption($name);
$this->assertEquals($newvalue, $value);
// Set value for display_option_download and then get it again. Check it hasn't changed.
$name = H5PCore::DISPLAY_OPTION_DOWNLOAD;
$newvalue = H5PDisplayOptionBehaviour::NEVER_SHOW;
$this->framework->setOption($name, $newvalue);
$value = $this->framework->getOption($name);
$expected = H5PDisplayOptionBehaviour::CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
$this->assertEquals($expected, $value);
}
/**
* Test the behaviour of updateContentFields().
*/
public function test_updateContentFields() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create 'Library1' library.
$library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
// Create 'Library2' library.
$library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
// Create an h5p content with 'Library1' as it's main library.
$h5pid = $generator->create_h5p_record($library1->id, 'iframe');
$updatedata = array(
'jsoncontent' => json_encode(['value' => 'test']),
'mainlibraryid' => $library2->id
);
// Update h5p content fields.
$this->framework->updateContentFields($h5pid, $updatedata);
// Get the h5p content from the DB.
$h5p = $DB->get_record('h5p', ['id' => $h5pid]);
$expected = json_encode(['value' => 'test']);
// Make sure the h5p content fields are properly updated.
$this->assertEquals($expected, $h5p->jsoncontent);
$this->assertEquals($library2->id, $h5p->mainlibraryid);
}
/**
* Test the behaviour of clearFilteredParameters().
*/
public function test_clearFilteredParameters() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create 3 libraries.
$library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
$library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
$library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2);
// Create h5p content with 'Library1' as a main library.
$h5pcontentid1 = $generator->create_h5p_record($library1->id);
// Create h5p content with 'Library1' as a main library.
$h5pcontentid2 = $generator->create_h5p_record($library1->id);
// Create h5p content with 'Library2' as a main library.
$h5pcontentid3 = $generator->create_h5p_record($library2->id);
// Create h5p content with 'Library3' as a main library.
$h5pcontentid4 = $generator->create_h5p_record($library3->id);
$h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
$h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
$h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
$h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
// The filtered parameters should be present in each h5p content.
$this->assertNotEmpty($h5pcontent1->filtered);
$this->assertNotEmpty($h5pcontent2->filtered);
$this->assertNotEmpty($h5pcontent3->filtered);
$this->assertNotEmpty($h5pcontent4->filtered);
// Clear the filtered parameters for contents that have library1 and library3 as
// their main library.
$this->framework->clearFilteredParameters([$library1->id, $library3->id]);
$h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
$h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
$h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
$h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
// The filtered parameters should be still present only for the content that has
// library 2 as a main library.
$this->assertEmpty($h5pcontent1->filtered);
$this->assertEmpty($h5pcontent2->filtered);
$this->assertNotEmpty($h5pcontent3->filtered);
$this->assertEmpty($h5pcontent4->filtered);
}
/**
* Test the behaviour of getNumNotFiltered().
*/
public function test_getNumNotFiltered() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create 3 libraries.
$library1 = $generator->create_library_record('Library1', 'Lib1', 1, 1, 2);
$library2 = $generator->create_library_record('Library2', 'Lib2', 1, 1, 2);
$library3 = $generator->create_library_record('Library3', 'Lib3', 1, 1, 2);
// Create h5p content with library1 as a main library.
$h5pcontentid1 = $generator->create_h5p_record($library1->id);
// Create h5p content with library1 as a main library.
$h5pcontentid2 = $generator->create_h5p_record($library1->id);
// Create h5p content with library2 as a main library.
$h5pcontentid3 = $generator->create_h5p_record($library2->id);
// Create h5p content with library3 as a main library.
$h5pcontentid4 = $generator->create_h5p_record($library3->id);
$h5pcontent1 = $DB->get_record('h5p', ['id' => $h5pcontentid1]);
$h5pcontent2 = $DB->get_record('h5p', ['id' => $h5pcontentid2]);
$h5pcontent3 = $DB->get_record('h5p', ['id' => $h5pcontentid3]);
$h5pcontent4 = $DB->get_record('h5p', ['id' => $h5pcontentid4]);
// The filtered parameters should be present in each h5p content.
$this->assertNotEmpty($h5pcontent1->filtered);
$this->assertNotEmpty($h5pcontent2->filtered);
$this->assertNotEmpty($h5pcontent3->filtered);
$this->assertNotEmpty($h5pcontent4->filtered);
// Clear the filtered parameters for contents that have library1 and library3 as
// their main library.
$this->framework->clearFilteredParameters([$library1->id, $library3->id]);
$countnotfiltered = $this->framework->getNumNotFiltered();
// 3 contents don't have their parameters filtered.
$this->assertEquals(3, $countnotfiltered);
}
/**
* Test the behaviour of getNumContent().
*/
public function test_getNumContent() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The 'MainLibrary' library data.
$mainlibrary = $data->mainlib->data;
// The 'Library1' library data.
$library1 = $data->lib1->data;
// Create new h5p content with MainLibrary as a main library.
$generator->create_h5p_record($mainlibrary->id);
// Get the number of h5p contents that are using 'MainLibrary' as their main library.
$countmainlib = $this->framework->getNumContent($mainlibrary->id);
// Get the number of h5p contents that are using 'Library1' as their main library.
$countlib1 = $this->framework->getNumContent($library1->id);
// Make sure that 2 contents are using MainLibrary as their main library.
$this->assertEquals(2, $countmainlib);
// Make sure that 0 contents are using Library1 as their main library.
$this->assertEquals(0, $countlib1);
}
/**
* Test the behaviour of getNumContent() when certain contents are being skipped.
*/
public function test_getNumContent_skip_content() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The 'MainLibrary' library data.
$mainlibrary = $data->mainlib->data;
// Create new h5p content with MainLibrary as a main library.
$h5pcontentid = $generator->create_h5p_record($mainlibrary->id);
// Get the number of h5p contents that are using 'MainLibrary' as their main library.
// Skip the newly created content $h5pcontentid.
$countmainlib = $this->framework->getNumContent($mainlibrary->id, [$h5pcontentid]);
// Make sure that 1 content is returned instead of 2 ($h5pcontentid being skipped).
$this->assertEquals(1, $countmainlib);
}
/**
* Test the behaviour of isContentSlugAvailable().
*/
public function test_isContentSlugAvailable() {
$this->resetAfterTest();
$slug = 'h5p-test-slug-1';
// Currently this returns always true. The slug is generated as a unique value for
// each h5p content and it is not stored in the h5p content table.
$isslugavailable = $this->framework->isContentSlugAvailable($slug);
$this->assertTrue($isslugavailable);
}
/**
* Test that a record is stored for cached assets.
*/
public function test_saveCachedAssets() {
global $DB;
$this->resetAfterTest();
$libraries = array(
array(
'machineName' => 'H5P.TestLib',
'libraryId' => 405,
),
array(
'FontAwesome' => 'FontAwesome',
'libraryId' => 406,
),
array(
'machineName' => 'H5P.SecondLib',
'libraryId' => 407,
),
);
$key = 'testhashkey';
$this->framework->saveCachedAssets($key, $libraries);
$records = $DB->get_records('h5p_libraries_cachedassets');
$this->assertCount(3, $records);
}
/**
* Test that the correct libraries are removed from the cached assets table
*/
public function test_deleteCachedAssets() {
global $DB;
$this->resetAfterTest();
$libraries = array(
array(
'machineName' => 'H5P.TestLib',
'libraryId' => 405,
),
array(
'FontAwesome' => 'FontAwesome',
'libraryId' => 406,
),
array(
'machineName' => 'H5P.SecondLib',
'libraryId' => 407,
),
);
$key1 = 'testhashkey';
$this->framework->saveCachedAssets($key1, $libraries);
$libraries = array(
array(
'machineName' => 'H5P.DiffLib',
'libraryId' => 408,
),
array(
'FontAwesome' => 'FontAwesome',
'libraryId' => 406,
),
array(
'machineName' => 'H5P.ThirdLib',
'libraryId' => 409,
),
);
$key2 = 'secondhashkey';
$this->framework->saveCachedAssets($key2, $libraries);
$libraries = array(
array(
'machineName' => 'H5P.AnotherDiffLib',
'libraryId' => 410,
),
array(
'FontAwesome' => 'NotRelated',
'libraryId' => 411,
),
array(
'machineName' => 'H5P.ForthLib',
'libraryId' => 412,
),
);
$key3 = 'threeforthewin';
$this->framework->saveCachedAssets($key3, $libraries);
$records = $DB->get_records('h5p_libraries_cachedassets');
$this->assertCount(9, $records);
// Selecting one library id will result in all related library entries also being deleted.
// Going to use the FontAwesome library id. The first two hashes should be returned.
$hashes = $this->framework->deleteCachedAssets(406);
$this->assertCount(2, $hashes);
$index = array_search($key1, $hashes);
$this->assertEquals($key1, $hashes[$index]);
$index = array_search($key2, $hashes);
$this->assertEquals($key2, $hashes[$index]);
$index = array_search($key3, $hashes);
$this->assertFalse($index);
// Check that the records have been removed as well.
$records = $DB->get_records('h5p_libraries_cachedassets');
$this->assertCount(3, $records);
}
/**
* Test the behaviour of getLibraryContentCount().
*/
public function test_getLibraryContentCount() {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Generate h5p related data.
$data = $generator->generate_h5p_data();
// The 'MainLibrary' library data.
$mainlibrary = $data->mainlib->data;
// The 'Library2' library data.
$library2 = $data->lib2->data;
// Create new h5p content with Library2 as it's main library.
$generator->create_h5p_record($library2->id);
// Create new h5p content with MainLibrary as it's main library.
$generator->create_h5p_record($mainlibrary->id);
$countlibrarycontent = $this->framework->getLibraryContentCount();
$expected = array(
"{$mainlibrary->machinename} {$mainlibrary->majorversion}.{$mainlibrary->minorversion}" => 2,
"{$library2->machinename} {$library2->majorversion}.{$library2->minorversion}" => 1,
);
// MainLibrary and Library1 are currently main libraries to the existing h5p contents.
// Should return the number of cases where MainLibrary and Library1 are main libraries to an h5p content.
$this->assertEquals($expected, $countlibrarycontent);
}
/**
* Test the behaviour of test_libraryHasUpgrade().
*
* @dataProvider libraryHasUpgrade_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param bool $expected The expectation whether the library is patched or not
**/
public function test_libraryHasUpgrade(array $libraryrecords, array $testlibrary, bool $expected): void {
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
foreach ($libraryrecords as $library) {
call_user_func_array([$generator, 'create_library_record'], $library);
}
$this->assertEquals($expected, $this->framework->libraryHasUpgrade($testlibrary));
}
/**
* Data provider for test_libraryHasUpgrade().
*
* @return array
*/
public function libraryHasUpgrade_provider(): array {
return [
'Lower major version; Identical lower version' => [
[
['Library', 'Lib', 2, 2],
],
[
'machineName' => 'Library',
'majorVersion' => 1,
'minorVersion' => 2
],
true,
],
'Major version identical; Lower minor version' => [
[
['Library', 'Lib', 2, 2],
],
[
'machineName' => 'Library',
'majorVersion' => 2,
'minorVersion' => 1
],
true,
],
'Major version identical; Minor version identical' => [
[
['Library', 'Lib', 2, 2],
],
[
'machineName' => 'Library',
'majorVersion' => 2,
'minorVersion' => 2
],
false,
],
'Major version higher; Minor version identical' => [
[
['Library', 'Lib', 2, 2],
],
[
'machineName' => 'Library',
'majorVersion' => 3,
'minorVersion' => 2
],
false,
],
'Major version identical; Minor version newer' => [
[
['Library', 'Lib', 2, 2],
],
[
'machineName' => 'Library',
'majorVersion' => 2,
'minorVersion' => 4
],
false,
]
];
}
/**
* Test the behaviour of get_latest_library_version().
*/
public function test_get_latest_library_version() {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
// Create a library record.
$machinename = 'TestLibrary';
$lib1 = $generator->create_library_record($machinename, 'Test', 1, 1, 2);
$lib2 = $generator->create_library_record($machinename, 'Test', 1, 2, 1);
$content = array(
'params' => json_encode(['param1' => 'Test']),
'library' => array(
'libraryId' => 0,
'machineName' => 'TestLibrary',
),
'disable' => 8
);
// Get the latest id (at this point, should be lib2).
$latestlib = $this->framework->get_latest_library_version($machinename);
$this->assertEquals($lib2->id, $latestlib->id);
// Get the latest id (at this point, should be lib3).
$lib3 = $generator->create_library_record($machinename, 'Test', 2, 1, 0);
$latestlib = $this->framework->get_latest_library_version($machinename);
$this->assertEquals($lib3->id, $latestlib->id);
// Get the latest id (at this point, should be still lib3).
$lib4 = $generator->create_library_record($machinename, 'Test', 1, 1, 3);
$latestlib = $this->framework->get_latest_library_version($machinename);
$this->assertEquals($lib3->id, $latestlib->id);
// Get the latest id (at this point, should be lib5).
$lib5 = $generator->create_library_record($machinename, 'Test', 2, 1, 6);
$latestlib = $this->framework->get_latest_library_version($machinename);
$this->assertEquals($lib5->id, $latestlib->id);
}
}