diff --git a/h5p/tests/framework_test.php b/h5p/tests/framework_test.php index 4042be17ad931..099844ba4e135 100644 --- a/h5p/tests/framework_test.php +++ b/h5p/tests/framework_test.php @@ -81,8 +81,9 @@ public function test_fetchExternalData_no_path_defined() { $this->resetAfterTest(); + $library = 'H5P.Accordion'; // Provide a valid URL to an external H5P content. - $url = "https://h5p.org/sites/default/files/h5p/exports/arithmetic-quiz-22-57860.h5p"; + $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); @@ -112,8 +113,9 @@ public function test_fetchExternalData_path_defined() { $this->resetAfterTest(); + $library = 'H5P.Accordion'; // Provide a valid URL to an external H5P content. - $url = "https://h5p.org/sites/default/files/h5p/exports/arithmetic-quiz-22-57860.h5p"; + $url = $this->getExternalTestFileUrl('/'.$library.'.h5p'); $h5pfolderpath = $CFG->tempdir . uniqid('/h5p-'); @@ -145,7 +147,7 @@ public function test_fetchExternalData_url_not_h5p() { $this->resetAfterTest(); // Provide an URL to an external file that is not an H5P content file. - $url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"; + $url = $this->getExternalTestFileUrl('/h5pcontenttypes.json'); $data = $this->framework->fetchExternalData($url, null, true); @@ -156,7 +158,7 @@ public function test_fetchExternalData_url_not_h5p() { // 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 . '.pdf')); + $this->assertTrue(file_exists($h5pfolderpath . '.json')); } /** diff --git a/h5p/tests/generator/lib.php b/h5p/tests/generator/lib.php index e9981a9264148..5f4654e957f60 100644 --- a/h5p/tests/generator/lib.php +++ b/h5p/tests/generator/lib.php @@ -23,7 +23,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -use core_h5p\factory; +use core_h5p\autoloader; +use core_h5p\core; defined('MOODLE_INTERNAL') || die(); @@ -343,30 +344,28 @@ public function create_library_dependency_record(int $libid, int $requiredlibid, } /** - * Create content type records in the h5p_libraries database table. + * Create H5P content type records in the h5p_libraries database table. * - * @param int $pending Number of content types not installed + * @param array $typestonotinstall H5P content types that should not be installed + * @param core $core h5p_test_core instance required to use the exttests URL * @return array Data of the content types not installed. */ - public function create_content_types(int $pending): array { + public function create_content_types(array $typestonotinstall, core $core): array { global $DB; - $factory = new factory(); - $core = $factory->get_core(); + autoloader::register(); // Get info of latest content types versions. $contenttypes = $core->get_latest_content_types()->contentTypes; - $size = count($contenttypes) - $pending; - - // Avoid to install 2 content types. - $chunks = array_chunk($contenttypes, $size); - - $contenttypes = $chunks[0]; - $pendingtypes = $chunks[1]; + $installedtypes = 0; // Fake installation of all other H5P content types. foreach ($contenttypes as $contenttype) { + // Don't install pending content types. + if (in_array($contenttype->id, $typestonotinstall)) { + continue; + } $library = [ 'machinename' => $contenttype->id, 'majorversion' => $contenttype->version->major, @@ -377,8 +376,9 @@ public function create_content_types(int $pending): array { 'coreminor' => $contenttype->coreApiVersionNeeded->minor ]; $DB->insert_record('h5p_libraries', (object) $library); + $installedtypes++; } - return [$contenttypes, $pendingtypes]; + return [$installedtypes, count($typestonotinstall)]; } } diff --git a/h5p/tests/h5p_core_test.php b/h5p/tests/h5p_core_test.php index 9bca6c6397ae7..27d8882f10de1 100644 --- a/h5p/tests/h5p_core_test.php +++ b/h5p/tests/h5p_core_test.php @@ -23,9 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -namespace core_h5p\local\tests; - -use core_h5p\factory; +namespace core_h5p; defined('MOODLE_INTERNAL') || die(); @@ -41,10 +39,16 @@ class h5p_core_test extends \advanced_testcase { protected function setup() { + global $CFG; parent::setUp(); - $factory = new factory(); + autoloader::register(); + + require_once($CFG->libdir . '/tests/fixtures/testable_core_h5p.php'); + + $factory = new h5p_test_factory(); $this->core = $factory->get_core(); + $this->core->set_endpoint($this->getExternalTestFileUrl('')); } /** @@ -54,12 +58,12 @@ protected function setup() { public function test_fetch_content_type(): void { global $DB; - $this->resetAfterTest(true); - if (!PHPUNIT_LONGTEST) { $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); } + $this->resetAfterTest(true); + // Get info of latest content types versions. $contenttypes = $this->core->get_latest_content_types()->contentTypes; // We are installing the first content type. @@ -95,27 +99,27 @@ public function test_fetch_content_type(): void { public function test_fetch_latest_content_types(): void { global $DB; - $this->resetAfterTest(true); - if (!PHPUNIT_LONGTEST) { $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); } + $this->resetAfterTest(true); + $contentfiles = $DB->count_records('h5p_libraries'); // Initially there are no h5p records in database. $this->assertEquals(0, $contentfiles); + $contenttypespending = ['H5P.Accordion']; + // Fetch generator. $generator = \testing_util::get_data_generator(); $h5pgenerator = $generator->get_plugin_generator('core_h5p'); // Get info of latest content types versions. - [$contenttypes, $contenttoinstall] = $h5pgenerator->create_content_types(1); + [$installedtypes, $typesnotinstalled] = $h5pgenerator->create_content_types($contenttypespending, $this->core); // Number of H5P content types. - $numcontenttypes = count($contenttypes) + count($contenttoinstall); - - $contenttoinstall = $contenttoinstall[0]; + $numcontenttypes = $installedtypes + $typesnotinstalled; // Content type libraries has runnable set to 1. $conditions = ['runnable' => 1]; @@ -123,7 +127,7 @@ public function test_fetch_latest_content_types(): void { // There is a record for each installed content type, except the one that was hold for later. $this->assertEquals($numcontenttypes - 1, count($contentfiles)); - $this->assertArrayNotHasKey($contenttoinstall->id, $contentfiles); + $this->assertArrayNotHasKey($contenttypespending[0], $contentfiles); $result = $this->core->fetch_latest_content_types(); @@ -131,9 +135,9 @@ public function test_fetch_latest_content_types(): void { // There is a new record for the new installed content type. $this->assertCount($numcontenttypes, $contentfiles); - $this->assertArrayHasKey($contenttoinstall->id, $contentfiles); + $this->assertArrayHasKey($contenttypespending[0], $contentfiles); $this->assertCount(1, $result->typesinstalled); - $this->assertStringStartsWith($contenttoinstall->id, $result->typesinstalled[0]['name']); + $this->assertStringStartsWith($contenttypespending[0], $result->typesinstalled[0]['name']); // New execution doesn't install any content type. $result = $this->core->fetch_latest_content_types(); diff --git a/lib/tests/fixtures/testable_core_h5p.php b/lib/tests/fixtures/testable_core_h5p.php new file mode 100644 index 0000000000000..1914c4f537952 --- /dev/null +++ b/lib/tests/fixtures/testable_core_h5p.php @@ -0,0 +1,102 @@ +. + +/** + * Fixture for testing the functionality of core_h5p. + * + * @package core + * @subpackage fixtures + * @category test + * @copyright 2019 Victor Deniz + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_h5p; + +defined('MOODLE_INTERNAL') || die(); + +/** + * H5P factory class stub for testing purposes. + * + * This class extends the real one to return the H5P core class stub. + * + * @copyright 2019 Victor Deniz + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class h5p_test_factory extends factory { + /** + * Returns an instance of the \core_h5p\core stub class. + * + * @return core_h5p\core + */ + public function get_core(): core { + if ($this->core === null ) { + $fs = new file_storage(); + $language = framework::get_language(); + $context = \context_system::instance(); + + $url = \moodle_url::make_pluginfile_url($context->id, 'core_h5p', '', null, + '', '')->out(); + + $this->core = new h5p_test_core($this->get_framework(), $fs, $url, $language, true); + } + + return $this->core; + } +} + +/** + * H5P core class stub for testing purposes. + * + * Modifies get_api_endpoint method to use local URLs. + * + * @copyright 2019 Victor Deniz + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class h5p_test_core extends core { + /** @var $endpoint Endpoint URL for testing H5P API */ + protected $endpoint; + + /** + * Set the endpoint URL + * + * @param string $url Endpoint URL + * @return void + */ + public function set_endpoint($url): void { + $this->endpoint = $url; + } + + /** + * Get the URL of the test endpoints instead of the H5P ones. + * + * If $library is null, moodle_url is the endpoint of the json test file with the H5P content types definition. If library is + * the machine name of a content type, moodle_url is the test URL for downloading the content type file. + * + * @param string|null $library The filename of the H5P content type file in external. + * @return \moodle_url The moodle_url of the file in external. + */ + public function get_api_endpoint(?string $library): \moodle_url { + + if ($library) { + $h5purl = $this->endpoint . '/' . $library . '.h5p'; + } else { + $h5purl = $h5purl = $this->endpoint . '/h5pcontenttypes.json'; + } + + return new \moodle_url($h5purl); + } +} \ No newline at end of file diff --git a/lib/tests/h5p_get_content_types_task_test.php b/lib/tests/h5p_get_content_types_task_test.php index a213cceafb23a..3ba655d738869 100644 --- a/lib/tests/h5p_get_content_types_task_test.php +++ b/lib/tests/h5p_get_content_types_task_test.php @@ -22,6 +22,9 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core_h5p\autoloader; +use core_h5p\h5p_test_factory; + defined('MOODLE_INTERNAL') || die(); /** @@ -35,12 +38,22 @@ */ class h5p_get_content_types_task_test extends advanced_testcase { + protected function setup() { + global $CFG; + parent::setUp(); + + autoloader::register(); + + require_once($CFG->libdir . '/tests/fixtures/testable_core_h5p.php'); + } + /** * Test task execution * * return void */ public function test_task_execution(): void { + if (!PHPUNIT_LONGTEST) { $this->markTestSkipped('PHPUNIT_LONGTEST is not defined'); } @@ -51,10 +64,23 @@ public function test_task_execution(): void { $generator = \testing_util::get_data_generator(); $h5pgenerator = $generator->get_plugin_generator('core_h5p'); - $h5pgenerator->create_content_types(2); + $factory = new h5p_test_factory(); + $core = $factory->get_core(); + $core->set_endpoint($this->getExternalTestFileUrl('')); + $contenttypespending = ['H5P.Accordion']; + + $h5pgenerator->create_content_types( $contenttypespending, $core); + + // Mock implementation of \core\task\h5p_get_content_types_task::get_core to avoid external systems. + $mocktask = $this->getMockBuilder(\core\task\h5p_get_content_types_task::class) + ->setMethods(['get_core']) + ->getMock(); + + $mocktask->expects($this->any()) + ->method('get_core') + ->willReturn($core); - $task = new \core\task\h5p_get_content_types_task(); - $task->execute(); - $this->expectOutputRegex('/2 new content types/'); + $mocktask->execute(); + $this->expectOutputRegex('/1 new content types/'); } }