Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
<?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_backup; /** > * Unit tests for the moodle1 converter > use backup; * > use convert_path; * @package core_backup > use convert_path_exception; * @subpackage backup-convert > use convert_factory; * @category phpunit > use convert_helper; * @copyright 2011 Mark Nielsen <mark@moodlerooms.com> > use moodle1_converter; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later > use moodle1_convert_empty_storage_exception; */ > use moodle1_convert_exception; > use moodle1_convert_storage_exception; defined('MOODLE_INTERNAL') || die(); > > defined('MOODLE_INTERNAL') || die(); global $CFG; > require_once($CFG->dirroot . '/backup/converter/moodle1/lib.php'); > global $CFG; > require_once($CFG->dirroot . '/backup/converter/moodle1/lib.php'); >
< * @category phpunit
> * @category test
< < defined('MOODLE_INTERNAL') || die(); < < global $CFG; < require_once($CFG->dirroot . '/backup/converter/moodle1/lib.php'); < < < class core_backup_moodle1_converter_testcase extends advanced_testcase {
> class moodle1_converter_test extends \advanced_testcase {
protected $iconhash;
< protected function setUp() {
> protected function setUp(): void {
global $CFG; $this->tempdir = convert_helper::generate_id('unittest'); $this->tempdirpath = make_backup_temp_directory($this->tempdir); check_dir_exists("$this->tempdirpath/course_files/sub1"); check_dir_exists("$this->tempdirpath/moddata/unittest/4/7"); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/moodle.xml", "$this->tempdirpath/moodle.xml" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", "$this->tempdirpath/course_files/file1.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", "$this->tempdirpath/course_files/sub1/file2.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", "$this->tempdirpath/moddata/unittest/4/file1.gif" ); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", "$this->tempdirpath/moddata/unittest/4/icon.gif" );
< $this->iconhash = file_storage::hash_from_path($this->tempdirpath.'/moddata/unittest/4/icon.gif');
> $this->iconhash = \file_storage::hash_from_path($this->tempdirpath.'/moddata/unittest/4/icon.gif');
copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif", "$this->tempdirpath/moddata/unittest/4/7/icon.gif" ); }
< protected function tearDown() {
> protected function tearDown(): void {
global $CFG; if (empty($CFG->keeptempdirectoriesonbackup)) { fulldelete($this->tempdirpath); } } public function test_detect_format() { $detected = moodle1_converter::detect_format($this->tempdir); $this->assertEquals(backup::FORMAT_MOODLE1, $detected); } public function test_convert_factory() { $converter = convert_factory::get_converter('moodle1', $this->tempdir); $this->assertInstanceOf('moodle1_converter', $converter); }
< /** < * @expectedException moodle1_convert_storage_exception < */
public function test_stash_storage_not_created() { $converter = convert_factory::get_converter('moodle1', $this->tempdir);
> $this->expectException(moodle1_convert_storage_exception::class);
$converter->set_stash('tempinfo', 12); }
< /** < * @expectedException moodle1_convert_empty_storage_exception < */
public function test_stash_requiring_empty_stash() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); $converter->set_stash('tempinfo', 12); try { $converter->get_stash('anothertempinfo'); } catch (moodle1_convert_empty_storage_exception $e) { // we must drop the storage here so we are able to re-create it in the next test
> $this->expectException(moodle1_convert_empty_storage_exception::class);
$converter->drop_stash_storage(); throw new moodle1_convert_empty_storage_exception('rethrowing'); } } public function test_stash_storage() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); // no implicit stashes $stashes = $converter->get_stash_names(); $this->assertEquals(gettype($stashes), 'array'); $this->assertTrue(empty($stashes)); // test stashes without itemid $converter->set_stash('tempinfo1', 12); $converter->set_stash('tempinfo2', array('a' => 2, 'b' => 3)); $stashes = $converter->get_stash_names(); $this->assertEquals('array', gettype($stashes)); $this->assertEquals(2, count($stashes)); $this->assertTrue(in_array('tempinfo1', $stashes)); $this->assertTrue(in_array('tempinfo2', $stashes)); $this->assertEquals(12, $converter->get_stash('tempinfo1')); $this->assertEquals(array('a' => 2, 'b' => 3), $converter->get_stash('tempinfo2')); // overwriting a stashed value is allowed $converter->set_stash('tempinfo1', '13'); $this->assertNotSame(13, $converter->get_stash('tempinfo1')); $this->assertSame('13', $converter->get_stash('tempinfo1')); // repeated reading is allowed $this->assertEquals('13', $converter->get_stash('tempinfo1')); // storing empty array $converter->set_stash('empty_array_stash', array()); $restored = $converter->get_stash('empty_array_stash'); //$this->assertEquals(gettype($restored), 'array'); // todo return null now, this needs MDL-27713 to be fixed, then uncomment $this->assertTrue(empty($restored)); // test stashes with itemid $converter->set_stash('tempinfo', 'Hello', 1); $converter->set_stash('tempinfo', 'World', 2); $this->assertSame('Hello', $converter->get_stash('tempinfo', 1)); $this->assertSame('World', $converter->get_stash('tempinfo', 2)); // test get_stash_itemids() $ids = $converter->get_stash_itemids('course_fileref'); $this->assertEquals(gettype($ids), 'array'); $this->assertTrue(empty($ids)); $converter->set_stash('course_fileref', null, 34); $converter->set_stash('course_fileref', null, 52); $ids = $converter->get_stash_itemids('course_fileref'); $this->assertEquals(2, count($ids)); $this->assertTrue(in_array(34, $ids)); $this->assertTrue(in_array(52, $ids)); $converter->drop_stash_storage(); } public function test_get_stash_or_default() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); $this->assertTrue(is_null($converter->get_stash_or_default('stashname'))); $this->assertTrue(is_null($converter->get_stash_or_default('stashname', 7))); $this->assertTrue('default' === $converter->get_stash_or_default('stashname', 0, 'default')); $this->assertTrue(array('foo', 'bar') === $converter->get_stash_or_default('stashname', 42, array('foo', 'bar'))); //$converter->set_stash('stashname', 0); //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed //$converter->set_stash('stashname', ''); //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed //$converter->set_stash('stashname', array()); //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed $converter->set_stash('stashname', 42); $this->assertTrue(42 === $converter->get_stash_or_default('stashname')); $this->assertTrue(is_null($converter->get_stash_or_default('stashname', 1))); $this->assertTrue(42 === $converter->get_stash_or_default('stashname', 0, 61)); $converter->set_stash('stashname', array(42 => (object)array('id' => 42)), 18); $stashed = $converter->get_stash_or_default('stashname', 18, 1984); $this->assertEquals(gettype($stashed), 'array'); $this->assertTrue(is_object($stashed[42])); $this->assertTrue($stashed[42]->id === 42); $converter->drop_stash_storage(); } public function test_get_contextid() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); // stash storage must be created in advance $converter->create_stash_storage(); // ids are generated on the first call $id1 = $converter->get_contextid(CONTEXT_BLOCK, 10); $id2 = $converter->get_contextid(CONTEXT_BLOCK, 11); $id3 = $converter->get_contextid(CONTEXT_MODULE, 10); $this->assertNotEquals($id1, $id2); $this->assertNotEquals($id1, $id3); $this->assertNotEquals($id2, $id3); // and then re-used if called with the same params $this->assertEquals($id1, $converter->get_contextid(CONTEXT_BLOCK, 10)); $this->assertEquals($id2, $converter->get_contextid(CONTEXT_BLOCK, 11)); $this->assertEquals($id3, $converter->get_contextid(CONTEXT_MODULE, 10)); // for system and course level, the instance is irrelevant // as we need only one system and one course $id1 = $converter->get_contextid(CONTEXT_COURSE); $id2 = $converter->get_contextid(CONTEXT_COURSE, 10); $id3 = $converter->get_contextid(CONTEXT_COURSE, 14); $this->assertEquals($id1, $id2); $this->assertEquals($id1, $id3); $id1 = $converter->get_contextid(CONTEXT_SYSTEM); $id2 = $converter->get_contextid(CONTEXT_SYSTEM, 11); $id3 = $converter->get_contextid(CONTEXT_SYSTEM, 15); $this->assertEquals($id1, $id2); $this->assertEquals($id1, $id3); $converter->drop_stash_storage(); } public function test_get_nextid() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $id1 = $converter->get_nextid(); $id2 = $converter->get_nextid(); $id3 = $converter->get_nextid(); $this->assertTrue(0 < $id1); $this->assertTrue($id1 < $id2); $this->assertTrue($id2 < $id3); } public function test_migrate_file() { $this->resetAfterTest(true); // set-up the file manager $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); $contextid = $converter->get_contextid(CONTEXT_MODULE, 32); $fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea'); // this fileman has not converted anything yet $fileids = $fileman->get_fileids(); $this->assertEquals(gettype($fileids), 'array'); $this->assertEquals(0, count($fileids)); // try to migrate an invalid file $fileman->itemid = 1; $thrown = false; try { $fileman->migrate_file('/../../../../../../../../../../../../../../etc/passwd'); } catch (moodle1_convert_exception $e) { $thrown = true; } $this->assertTrue($thrown); // migrate a single file $fileman->itemid = 4; $fileman->migrate_file('moddata/unittest/4/icon.gif'); $subdir = substr($this->iconhash, 0, 2); $this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash)); // get the file id $fileids = $fileman->get_fileids(); $this->assertEquals(gettype($fileids), 'array'); $this->assertEquals(1, count($fileids)); // migrate another single file into another file area $fileman->filearea = 'anotherarea'; $fileman->itemid = 7; $fileman->migrate_file('moddata/unittest/4/7/icon.gif', '/', 'renamed.gif'); // get the file records $filerecordids = $converter->get_stash_itemids('files'); foreach ($filerecordids as $filerecordid) { $filerecord = $converter->get_stash('files', $filerecordid); $this->assertEquals($this->iconhash, $filerecord['contenthash']); $this->assertEquals($contextid, $filerecord['contextid']); $this->assertEquals('mod_unittest', $filerecord['component']); if ($filerecord['filearea'] === 'testarea') { $this->assertEquals(4, $filerecord['itemid']); $this->assertEquals('icon.gif', $filerecord['filename']); } } // explicitly clear the list of migrated files $this->assertTrue(count($fileman->get_fileids()) > 0); $fileman->reset_fileids(); $this->assertTrue(count($fileman->get_fileids()) == 0); $converter->drop_stash_storage(); } public function test_migrate_directory() { $this->resetAfterTest(true); // Set-up the file manager. $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); $contextid = $converter->get_contextid(CONTEXT_MODULE, 32); $fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea'); // This fileman has not converted anything yet. $fileids = $fileman->get_fileids(); $this->assertEquals(gettype($fileids), 'array'); $this->assertEquals(0, count($fileids)); // Try to migrate a non-existing directory. $returned = $fileman->migrate_directory('not/existing/directory'); $this->assertEquals(gettype($returned), 'array'); $this->assertEquals(0, count($returned)); $fileids = $fileman->get_fileids(); $this->assertEquals(gettype($fileids), 'array'); $this->assertEquals(0, count($fileids)); // Try to migrate whole course_files. $returned = $fileman->migrate_directory('course_files'); $this->assertEquals(gettype($returned), 'array'); $this->assertEquals(4, count($returned)); // Two files, two directories. $fileids = $fileman->get_fileids(); $this->assertEquals(gettype($fileids), 'array'); $this->assertEquals(4, count($fileids)); $subdir = substr($this->iconhash, 0, 2); $this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash)); // Check the file records. $files = array(); $filerecordids = $converter->get_stash_itemids('files'); foreach ($filerecordids as $filerecordid) { $filerecord = $converter->get_stash('files', $filerecordid); $files[$filerecord['filepath'].$filerecord['filename']] = $filerecord; } $this->assertEquals('array', gettype($files['/.'])); $this->assertEquals('array', gettype($files['/file1.gif'])); $this->assertEquals('array', gettype($files['/sub1/.'])); $this->assertEquals('array', gettype($files['/sub1/file2.gif']));
< $this->assertEquals(file_storage::hash_from_string(''), $files['/.']['contenthash']); < $this->assertEquals(file_storage::hash_from_string(''), $files['/sub1/.']['contenthash']);
> $this->assertEquals(\file_storage::hash_from_string(''), $files['/.']['contenthash']); > $this->assertEquals(\file_storage::hash_from_string(''), $files['/sub1/.']['contenthash']);
$this->assertEquals($this->iconhash, $files['/file1.gif']['contenthash']); $this->assertEquals($this->iconhash, $files['/sub1/file2.gif']['contenthash']); $converter->drop_stash_storage(); } public function test_migrate_directory_with_trailing_slash() { $this->resetAfterTest(true); // Set-up the file manager. $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->create_stash_storage(); $contextid = $converter->get_contextid(CONTEXT_MODULE, 32); $fileman = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea'); // Try to migrate a subdirectory passed with the trailing slash. $returned = $fileman->migrate_directory('course_files/sub1/'); // Debugging message must be thrown in this case. $this->assertDebuggingCalled(null, DEBUG_DEVELOPER); $this->assertEquals(gettype($returned), 'array'); $this->assertEquals(2, count($returned)); // One file, one directory. $converter->drop_stash_storage(); } public function test_convert_path() { $path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR'); $this->assertEquals('foo_bar', $path->get_name()); $this->assertEquals('/ROOT/THINGS/FOO/BAR', $path->get_path()); $this->assertEquals('process_foo_bar', $path->get_processing_method()); $this->assertEquals('on_foo_bar_start', $path->get_start_method()); $this->assertEquals('on_foo_bar_end', $path->get_end_method()); } public function test_convert_path_implicit_recipes() { $path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR'); $data = array( 'ID' => 76, 'ELOY' => 'stronk7', 'MARTIN' => 'moodler', 'EMPTY' => null, ); // apply default recipes (converting keys to lowercase) $data = $path->apply_recipes($data); $this->assertEquals(4, count($data)); $this->assertEquals(76, $data['id']); $this->assertEquals('stronk7', $data['eloy']); $this->assertEquals('moodler', $data['martin']); $this->assertSame(null, $data['empty']); } public function test_convert_path_explicit_recipes() { $path = new convert_path( 'foo_bar', '/ROOT/THINGS/FOO/BAR', array( 'newfields' => array( 'david' => 'mudrd8mz', 'petr' => 'skodak', ), 'renamefields' => array( 'empty' => 'nothing', ), 'dropfields' => array( 'id' ), ) ); $data = array( 'ID' => 76, 'ELOY' => 'stronk7', 'MARTIN' => 'moodler', 'EMPTY' => null, ); $data = $path->apply_recipes($data); $this->assertEquals(5, count($data)); $this->assertFalse(array_key_exists('id', $data)); $this->assertEquals('stronk7', $data['eloy']); $this->assertEquals('moodler', $data['martin']); $this->assertEquals('mudrd8mz', $data['david']); $this->assertEquals('skodak', $data['petr']); $this->assertSame(null, $data['nothing']); }
< /** < * @expectedException convert_path_exception < */
public function test_grouped_data_on_nongrouped_convert_path() { // prepare some grouped data $data = array( 'ID' => 77, 'NAME' => 'Pale lagers', 'BEERS' => array( array( 'BEER' => array( 'ID' => 67, 'NAME' => 'Pilsner Urquell', ) ), array( 'BEER' => array( 'ID' => 34, 'NAME' => 'Heineken', ) ), ) ); // declare a non-grouped path $path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE'); // an attempt to apply recipes throws exception because we do not expect grouped data
> $this->expectException(convert_path_exception::class);
$data = $path->apply_recipes($data); }
< /** < * @expectedException convert_path_exception < */
public function test_grouped_convert_path_with_recipes() { // prepare some grouped data $data = array( 'ID' => 77, 'NAME' => 'Pale lagers', 'BEERS' => array( array( 'BEER' => array( 'ID' => 67, 'NAME' => 'Pilsner Urquell', ) ), array( 'BEER' => array( 'ID' => 34, 'NAME' => 'Heineken', ) ), ) ); // implict recipes work for grouped data if the path is declared as grouped $path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE', array(), true); $data = $path->apply_recipes($data); $this->assertEquals('Heineken', $data['beers'][1]['beer']['name']); // an attempt to provide explicit recipes on grouped elements throws exception
> $this->expectException(convert_path_exception::class);
$path = new convert_path( 'beer_style', '/ROOT/BEER_STYLES/BEER_STYLE', array( 'renamefields' => array( 'name' => 'beername', // note this is confusing recipe because the 'name' is used for both // beer-style name ('Pale lagers') and beer name ('Pilsner Urquell') ) ), true); } public function test_referenced_course_files() { $text = 'This is a text containing links to file.php as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif" /><a href="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif$@FORCEDOWNLOAD@$">download image</a><br /> <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div> <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div> <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />'; $files = moodle1_converter::find_referenced_files($text); $this->assertEquals(gettype($files), 'array'); $this->assertEquals(2, count($files)); $this->assertTrue(in_array('/pics/news.gif', $files)); $this->assertTrue(in_array('/MANUAL.DOC', $files)); $text = moodle1_converter::rewrite_filephp_usage($text, array('/pics/news.gif', '/another/file/notused.txt')); $this->assertEquals($text, 'This is a text containing links to file.php as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="@@PLUGINFILE@@/pics/news.gif" /><a href="@@PLUGINFILE@@/pics/news.gif?forcedownload=1">download image</a><br /> <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div> <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div> <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />'); } public function test_referenced_files_urlencoded() { $text = 'This is a text containing links to file.php as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif" /><a href="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif$@FORCEDOWNLOAD@$">no space</a><br /> <br /><a href=\'$@FILEPHP@$$@SLASH@$pics$@SLASH@$news%20with%20spaces.gif$@FORCEDOWNLOAD@$\'>with urlencoded spaces</a><br /> <a href="$@FILEPHP@$$@SLASH@$illegal%20pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (space and plus encoded)</a> <a href="$@FILEPHP@$$@SLASH@$illegal pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (none encoded)</a> <a href="$@FILEPHP@$$@SLASH@$illegal%20pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (only space encoded)</a> <a href="$@FILEPHP@$$@SLASH@$illegal pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (only plus)</a>'; $files = moodle1_converter::find_referenced_files($text); $this->assertEquals(gettype($files), 'array'); $this->assertEquals(3, count($files)); $this->assertTrue(in_array('/pics/news.gif', $files)); $this->assertTrue(in_array('/pics/news with spaces.gif', $files)); $this->assertTrue(in_array('/illegal pics+movies/romeo+juliet.avi', $files)); $text = moodle1_converter::rewrite_filephp_usage($text, $files); $this->assertEquals('This is a text containing links to file.php as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="@@PLUGINFILE@@/pics/news.gif" /><a href="@@PLUGINFILE@@/pics/news.gif?forcedownload=1">no space</a><br /> <br /><a href=\'@@PLUGINFILE@@/pics/news%20with%20spaces.gif?forcedownload=1\'>with urlencoded spaces</a><br /> <a href="@@PLUGINFILE@@/illegal%20pics%2Bmovies/romeo%2Bjuliet.avi">Download the full AVI for free! (space and plus encoded)</a> <a href="@@PLUGINFILE@@/illegal%20pics%2Bmovies/romeo%2Bjuliet.avi">Download the full AVI for free! (none encoded)</a> <a href="$@FILEPHP@$$@SLASH@$illegal%20pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (only space encoded)</a> <a href="$@FILEPHP@$$@SLASH@$illegal pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (only plus)</a>', $text); } public function test_question_bank_conversion() { global $CFG; $this->resetAfterTest(true); copy( "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/questions.xml", "$this->tempdirpath/moodle.xml" ); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->convert(); } public function test_convert_run_convert() { $this->resetAfterTest(true); $converter = convert_factory::get_converter('moodle1', $this->tempdir); $converter->convert(); } public function test_inforef_manager() { $converter = convert_factory::get_converter('moodle1', $this->tempdir); $inforef = $converter->get_inforef_manager('unittest'); $inforef->add_ref('file', 45); $inforef->add_refs('file', array(46, 47)); // todo test the write_refs() via some dummy xml_writer $this->expectException('coding_exception'); $inforef->add_ref('unknown_referenced_item_name', 76); } }