Skip to content

Commit

Permalink
MDL-67296 core_h5p: tests modified to use exttests
Browse files Browse the repository at this point in the history
  • Loading branch information
vmdef committed Jan 22, 2020
1 parent d8fe1ed commit e942844
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 37 deletions.
10 changes: 6 additions & 4 deletions h5p/tests/framework_test.php
Expand Up @@ -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);
Expand Down Expand Up @@ -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-');

Expand Down Expand Up @@ -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);

Expand All @@ -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'));
}

/**
Expand Down
28 changes: 14 additions & 14 deletions h5p/tests/generator/lib.php
Expand Up @@ -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();

Expand Down Expand Up @@ -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,
Expand All @@ -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)];
}
}
34 changes: 19 additions & 15 deletions h5p/tests/h5p_core_test.php
Expand Up @@ -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();

Expand All @@ -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(''));
}

/**
Expand All @@ -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.
Expand Down Expand Up @@ -95,45 +99,45 @@ 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];
$contentfiles = $DB->get_records('h5p_libraries', $conditions, '', 'machinename');

// 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();

$contentfiles = $DB->get_records('h5p_libraries', $conditions, '', 'machinename');

// 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();
Expand Down
102 changes: 102 additions & 0 deletions lib/tests/fixtures/testable_core_h5p.php
@@ -0,0 +1,102 @@
<?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/>.

/**
* Fixture for testing the functionality of core_h5p.
*
* @package core
* @subpackage fixtures
* @category test
* @copyright 2019 Victor Deniz <victor@moodle.com>
* @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 <victor@moodle.com>
* @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 <victor@moodle.com>
* @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);
}
}
34 changes: 30 additions & 4 deletions lib/tests/h5p_get_content_types_task_test.php
Expand Up @@ -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();

/**
Expand All @@ -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');
}
Expand All @@ -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/');
}
}

0 comments on commit e942844

Please sign in to comment.