Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Unit tests for the moodle1 converter
  19   *
  20   * @package    core_backup
  21   * @subpackage backup-convert
  22   * @category   phpunit
  23   * @copyright  2011 Mark Nielsen <mark@moodlerooms.com>
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once($CFG->dirroot . '/backup/converter/moodle1/lib.php');
  31  
  32  
  33  class core_backup_moodle1_converter_testcase extends advanced_testcase {
  34  
  35      /** @var string the name of the directory containing the unpacked Moodle 1.9 backup */
  36      protected $tempdir;
  37  
  38      /** @var string the full name of the directory containing the unpacked Moodle 1.9 backup */
  39      protected $tempdirpath;
  40  
  41      /** @var string saved hash of an icon file used during testing */
  42      protected $iconhash;
  43  
  44      protected function setUp() {
  45          global $CFG;
  46  
  47          $this->tempdir = convert_helper::generate_id('unittest');
  48          $this->tempdirpath = make_backup_temp_directory($this->tempdir);
  49          check_dir_exists("$this->tempdirpath/course_files/sub1");
  50          check_dir_exists("$this->tempdirpath/moddata/unittest/4/7");
  51          copy(
  52              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/moodle.xml",
  53              "$this->tempdirpath/moodle.xml"
  54          );
  55          copy(
  56              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
  57              "$this->tempdirpath/course_files/file1.gif"
  58          );
  59          copy(
  60              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
  61              "$this->tempdirpath/course_files/sub1/file2.gif"
  62          );
  63          copy(
  64              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
  65              "$this->tempdirpath/moddata/unittest/4/file1.gif"
  66          );
  67          copy(
  68              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
  69              "$this->tempdirpath/moddata/unittest/4/icon.gif"
  70          );
  71          $this->iconhash = file_storage::hash_from_path($this->tempdirpath.'/moddata/unittest/4/icon.gif');
  72          copy(
  73              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
  74              "$this->tempdirpath/moddata/unittest/4/7/icon.gif"
  75          );
  76      }
  77  
  78      protected function tearDown() {
  79          global $CFG;
  80          if (empty($CFG->keeptempdirectoriesonbackup)) {
  81              fulldelete($this->tempdirpath);
  82          }
  83      }
  84  
  85      public function test_detect_format() {
  86          $detected = moodle1_converter::detect_format($this->tempdir);
  87          $this->assertEquals(backup::FORMAT_MOODLE1, $detected);
  88      }
  89  
  90      public function test_convert_factory() {
  91          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
  92          $this->assertInstanceOf('moodle1_converter', $converter);
  93      }
  94  
  95      /**
  96       * @expectedException moodle1_convert_storage_exception
  97       */
  98      public function test_stash_storage_not_created() {
  99          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 100          $converter->set_stash('tempinfo', 12);
 101      }
 102  
 103      /**
 104       * @expectedException moodle1_convert_empty_storage_exception
 105       */
 106      public function test_stash_requiring_empty_stash() {
 107          $this->resetAfterTest(true);
 108          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 109          $converter->create_stash_storage();
 110          $converter->set_stash('tempinfo', 12);
 111          try {
 112              $converter->get_stash('anothertempinfo');
 113  
 114          } catch (moodle1_convert_empty_storage_exception $e) {
 115              // we must drop the storage here so we are able to re-create it in the next test
 116              $converter->drop_stash_storage();
 117              throw new moodle1_convert_empty_storage_exception('rethrowing');
 118          }
 119      }
 120  
 121      public function test_stash_storage() {
 122          $this->resetAfterTest(true);
 123          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 124          $converter->create_stash_storage();
 125  
 126          // no implicit stashes
 127          $stashes = $converter->get_stash_names();
 128          $this->assertEquals(gettype($stashes), 'array');
 129          $this->assertTrue(empty($stashes));
 130  
 131          // test stashes without itemid
 132          $converter->set_stash('tempinfo1', 12);
 133          $converter->set_stash('tempinfo2', array('a' => 2, 'b' => 3));
 134          $stashes = $converter->get_stash_names();
 135          $this->assertEquals('array', gettype($stashes));
 136          $this->assertEquals(2, count($stashes));
 137          $this->assertTrue(in_array('tempinfo1', $stashes));
 138          $this->assertTrue(in_array('tempinfo2', $stashes));
 139          $this->assertEquals(12, $converter->get_stash('tempinfo1'));
 140          $this->assertEquals(array('a' => 2, 'b' => 3), $converter->get_stash('tempinfo2'));
 141  
 142          // overwriting a stashed value is allowed
 143          $converter->set_stash('tempinfo1', '13');
 144          $this->assertNotSame(13, $converter->get_stash('tempinfo1'));
 145          $this->assertSame('13', $converter->get_stash('tempinfo1'));
 146  
 147          // repeated reading is allowed
 148          $this->assertEquals('13', $converter->get_stash('tempinfo1'));
 149  
 150          // storing empty array
 151          $converter->set_stash('empty_array_stash', array());
 152          $restored = $converter->get_stash('empty_array_stash');
 153          //$this->assertEquals(gettype($restored), 'array'); // todo return null now, this needs MDL-27713 to be fixed, then uncomment
 154          $this->assertTrue(empty($restored));
 155  
 156          // test stashes with itemid
 157          $converter->set_stash('tempinfo', 'Hello', 1);
 158          $converter->set_stash('tempinfo', 'World', 2);
 159          $this->assertSame('Hello', $converter->get_stash('tempinfo', 1));
 160          $this->assertSame('World', $converter->get_stash('tempinfo', 2));
 161  
 162          // test get_stash_itemids()
 163          $ids = $converter->get_stash_itemids('course_fileref');
 164          $this->assertEquals(gettype($ids), 'array');
 165          $this->assertTrue(empty($ids));
 166  
 167          $converter->set_stash('course_fileref', null, 34);
 168          $converter->set_stash('course_fileref', null, 52);
 169          $ids = $converter->get_stash_itemids('course_fileref');
 170          $this->assertEquals(2, count($ids));
 171          $this->assertTrue(in_array(34, $ids));
 172          $this->assertTrue(in_array(52, $ids));
 173  
 174          $converter->drop_stash_storage();
 175      }
 176  
 177      public function test_get_stash_or_default() {
 178          $this->resetAfterTest(true);
 179          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 180          $converter->create_stash_storage();
 181  
 182          $this->assertTrue(is_null($converter->get_stash_or_default('stashname')));
 183          $this->assertTrue(is_null($converter->get_stash_or_default('stashname', 7)));
 184          $this->assertTrue('default' === $converter->get_stash_or_default('stashname', 0, 'default'));
 185          $this->assertTrue(array('foo', 'bar') === $converter->get_stash_or_default('stashname', 42, array('foo', 'bar')));
 186  
 187          //$converter->set_stash('stashname', 0);
 188          //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
 189  
 190          //$converter->set_stash('stashname', '');
 191          //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
 192  
 193          //$converter->set_stash('stashname', array());
 194          //$this->assertFalse(is_null($converter->get_stash_or_default('stashname'))); // todo returns true now, this needs MDL-27713 to be fixed
 195  
 196          $converter->set_stash('stashname', 42);
 197          $this->assertTrue(42 === $converter->get_stash_or_default('stashname'));
 198          $this->assertTrue(is_null($converter->get_stash_or_default('stashname', 1)));
 199          $this->assertTrue(42 === $converter->get_stash_or_default('stashname', 0, 61));
 200  
 201          $converter->set_stash('stashname', array(42 => (object)array('id' => 42)), 18);
 202          $stashed = $converter->get_stash_or_default('stashname', 18, 1984);
 203          $this->assertEquals(gettype($stashed), 'array');
 204          $this->assertTrue(is_object($stashed[42]));
 205          $this->assertTrue($stashed[42]->id === 42);
 206  
 207          $converter->drop_stash_storage();
 208      }
 209  
 210      public function test_get_contextid() {
 211          $this->resetAfterTest(true);
 212  
 213          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 214  
 215          // stash storage must be created in advance
 216          $converter->create_stash_storage();
 217  
 218          // ids are generated on the first call
 219          $id1 = $converter->get_contextid(CONTEXT_BLOCK, 10);
 220          $id2 = $converter->get_contextid(CONTEXT_BLOCK, 11);
 221          $id3 = $converter->get_contextid(CONTEXT_MODULE, 10);
 222  
 223          $this->assertNotEquals($id1, $id2);
 224          $this->assertNotEquals($id1, $id3);
 225          $this->assertNotEquals($id2, $id3);
 226  
 227          // and then re-used if called with the same params
 228          $this->assertEquals($id1, $converter->get_contextid(CONTEXT_BLOCK, 10));
 229          $this->assertEquals($id2, $converter->get_contextid(CONTEXT_BLOCK, 11));
 230          $this->assertEquals($id3, $converter->get_contextid(CONTEXT_MODULE, 10));
 231  
 232          // for system and course level, the instance is irrelevant
 233          // as we need only one system and one course
 234          $id1 = $converter->get_contextid(CONTEXT_COURSE);
 235          $id2 = $converter->get_contextid(CONTEXT_COURSE, 10);
 236          $id3 = $converter->get_contextid(CONTEXT_COURSE, 14);
 237  
 238          $this->assertEquals($id1, $id2);
 239          $this->assertEquals($id1, $id3);
 240  
 241          $id1 = $converter->get_contextid(CONTEXT_SYSTEM);
 242          $id2 = $converter->get_contextid(CONTEXT_SYSTEM, 11);
 243          $id3 = $converter->get_contextid(CONTEXT_SYSTEM, 15);
 244  
 245          $this->assertEquals($id1, $id2);
 246          $this->assertEquals($id1, $id3);
 247  
 248          $converter->drop_stash_storage();
 249      }
 250  
 251      public function test_get_nextid() {
 252          $this->resetAfterTest(true);
 253  
 254          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 255  
 256          $id1 = $converter->get_nextid();
 257          $id2 = $converter->get_nextid();
 258          $id3 = $converter->get_nextid();
 259  
 260          $this->assertTrue(0 < $id1);
 261          $this->assertTrue($id1 < $id2);
 262          $this->assertTrue($id2 < $id3);
 263      }
 264  
 265      public function test_migrate_file() {
 266          $this->resetAfterTest(true);
 267  
 268          // set-up the file manager
 269          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 270          $converter->create_stash_storage();
 271          $contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
 272          $fileman   = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
 273          // this fileman has not converted anything yet
 274          $fileids = $fileman->get_fileids();
 275          $this->assertEquals(gettype($fileids), 'array');
 276          $this->assertEquals(0, count($fileids));
 277          // try to migrate an invalid file
 278          $fileman->itemid = 1;
 279          $thrown = false;
 280          try {
 281              $fileman->migrate_file('/../../../../../../../../../../../../../../etc/passwd');
 282          } catch (moodle1_convert_exception $e) {
 283              $thrown = true;
 284          }
 285          $this->assertTrue($thrown);
 286          // migrate a single file
 287          $fileman->itemid = 4;
 288          $fileman->migrate_file('moddata/unittest/4/icon.gif');
 289          $subdir = substr($this->iconhash, 0, 2);
 290          $this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash));
 291          // get the file id
 292          $fileids = $fileman->get_fileids();
 293          $this->assertEquals(gettype($fileids), 'array');
 294          $this->assertEquals(1, count($fileids));
 295          // migrate another single file into another file area
 296          $fileman->filearea = 'anotherarea';
 297          $fileman->itemid = 7;
 298          $fileman->migrate_file('moddata/unittest/4/7/icon.gif', '/', 'renamed.gif');
 299          // get the file records
 300          $filerecordids = $converter->get_stash_itemids('files');
 301          foreach ($filerecordids as $filerecordid) {
 302              $filerecord = $converter->get_stash('files', $filerecordid);
 303              $this->assertEquals($this->iconhash, $filerecord['contenthash']);
 304              $this->assertEquals($contextid, $filerecord['contextid']);
 305              $this->assertEquals('mod_unittest', $filerecord['component']);
 306              if ($filerecord['filearea'] === 'testarea') {
 307                  $this->assertEquals(4, $filerecord['itemid']);
 308                  $this->assertEquals('icon.gif', $filerecord['filename']);
 309              }
 310          }
 311          // explicitly clear the list of migrated files
 312          $this->assertTrue(count($fileman->get_fileids()) > 0);
 313          $fileman->reset_fileids();
 314          $this->assertTrue(count($fileman->get_fileids()) == 0);
 315          $converter->drop_stash_storage();
 316      }
 317  
 318      public function test_migrate_directory() {
 319          $this->resetAfterTest(true);
 320  
 321          // Set-up the file manager.
 322          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 323          $converter->create_stash_storage();
 324          $contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
 325          $fileman   = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
 326          // This fileman has not converted anything yet.
 327          $fileids = $fileman->get_fileids();
 328          $this->assertEquals(gettype($fileids), 'array');
 329          $this->assertEquals(0, count($fileids));
 330          // Try to migrate a non-existing directory.
 331          $returned = $fileman->migrate_directory('not/existing/directory');
 332          $this->assertEquals(gettype($returned), 'array');
 333          $this->assertEquals(0, count($returned));
 334          $fileids = $fileman->get_fileids();
 335          $this->assertEquals(gettype($fileids), 'array');
 336          $this->assertEquals(0, count($fileids));
 337          // Try to migrate whole course_files.
 338          $returned = $fileman->migrate_directory('course_files');
 339          $this->assertEquals(gettype($returned), 'array');
 340          $this->assertEquals(4, count($returned)); // Two files, two directories.
 341          $fileids = $fileman->get_fileids();
 342          $this->assertEquals(gettype($fileids), 'array');
 343          $this->assertEquals(4, count($fileids));
 344          $subdir = substr($this->iconhash, 0, 2);
 345          $this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash));
 346  
 347          // Check the file records.
 348          $files = array();
 349          $filerecordids = $converter->get_stash_itemids('files');
 350          foreach ($filerecordids as $filerecordid) {
 351              $filerecord = $converter->get_stash('files', $filerecordid);
 352              $files[$filerecord['filepath'].$filerecord['filename']] = $filerecord;
 353          }
 354          $this->assertEquals('array', gettype($files['/.']));
 355          $this->assertEquals('array', gettype($files['/file1.gif']));
 356          $this->assertEquals('array', gettype($files['/sub1/.']));
 357          $this->assertEquals('array', gettype($files['/sub1/file2.gif']));
 358          $this->assertEquals(file_storage::hash_from_string(''), $files['/.']['contenthash']);
 359          $this->assertEquals(file_storage::hash_from_string(''), $files['/sub1/.']['contenthash']);
 360          $this->assertEquals($this->iconhash, $files['/file1.gif']['contenthash']);
 361          $this->assertEquals($this->iconhash, $files['/sub1/file2.gif']['contenthash']);
 362  
 363          $converter->drop_stash_storage();
 364      }
 365  
 366      public function test_migrate_directory_with_trailing_slash() {
 367          $this->resetAfterTest(true);
 368  
 369          // Set-up the file manager.
 370          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 371          $converter->create_stash_storage();
 372          $contextid = $converter->get_contextid(CONTEXT_MODULE, 32);
 373          $fileman   = $converter->get_file_manager($contextid, 'mod_unittest', 'testarea');
 374          // Try to migrate a subdirectory passed with the trailing slash.
 375          $returned = $fileman->migrate_directory('course_files/sub1/');
 376          // Debugging message must be thrown in this case.
 377          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 378          $this->assertEquals(gettype($returned), 'array');
 379          $this->assertEquals(2, count($returned)); // One file, one directory.
 380  
 381          $converter->drop_stash_storage();
 382      }
 383  
 384      public function test_convert_path() {
 385          $path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR');
 386          $this->assertEquals('foo_bar', $path->get_name());
 387          $this->assertEquals('/ROOT/THINGS/FOO/BAR', $path->get_path());
 388          $this->assertEquals('process_foo_bar', $path->get_processing_method());
 389          $this->assertEquals('on_foo_bar_start', $path->get_start_method());
 390          $this->assertEquals('on_foo_bar_end', $path->get_end_method());
 391      }
 392  
 393      public function test_convert_path_implicit_recipes() {
 394          $path = new convert_path('foo_bar', '/ROOT/THINGS/FOO/BAR');
 395          $data = array(
 396              'ID' => 76,
 397              'ELOY' => 'stronk7',
 398              'MARTIN' => 'moodler',
 399              'EMPTY' => null,
 400          );
 401          // apply default recipes (converting keys to lowercase)
 402          $data = $path->apply_recipes($data);
 403          $this->assertEquals(4, count($data));
 404          $this->assertEquals(76, $data['id']);
 405          $this->assertEquals('stronk7', $data['eloy']);
 406          $this->assertEquals('moodler', $data['martin']);
 407          $this->assertSame(null, $data['empty']);
 408      }
 409  
 410      public function test_convert_path_explicit_recipes() {
 411          $path = new convert_path(
 412              'foo_bar', '/ROOT/THINGS/FOO/BAR',
 413              array(
 414                  'newfields' => array(
 415                      'david' => 'mudrd8mz',
 416                      'petr'  => 'skodak',
 417                  ),
 418                  'renamefields' => array(
 419                      'empty' => 'nothing',
 420                  ),
 421                  'dropfields' => array(
 422                      'id'
 423                  ),
 424              )
 425          );
 426          $data = array(
 427              'ID' => 76,
 428              'ELOY' => 'stronk7',
 429              'MARTIN' => 'moodler',
 430              'EMPTY' => null,
 431          );
 432          $data = $path->apply_recipes($data);
 433  
 434          $this->assertEquals(5, count($data));
 435          $this->assertFalse(array_key_exists('id', $data));
 436          $this->assertEquals('stronk7', $data['eloy']);
 437          $this->assertEquals('moodler', $data['martin']);
 438          $this->assertEquals('mudrd8mz', $data['david']);
 439          $this->assertEquals('skodak', $data['petr']);
 440          $this->assertSame(null, $data['nothing']);
 441      }
 442  
 443      /**
 444       * @expectedException convert_path_exception
 445       */
 446      public function test_grouped_data_on_nongrouped_convert_path() {
 447          // prepare some grouped data
 448          $data = array(
 449              'ID' => 77,
 450              'NAME' => 'Pale lagers',
 451              'BEERS' => array(
 452                  array(
 453                      'BEER' => array(
 454                          'ID' => 67,
 455                          'NAME' => 'Pilsner Urquell',
 456                      )
 457                  ),
 458                  array(
 459                      'BEER' => array(
 460                          'ID' => 34,
 461                          'NAME' => 'Heineken',
 462                      )
 463                  ),
 464              )
 465          );
 466  
 467          // declare a non-grouped path
 468          $path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE');
 469  
 470          // an attempt to apply recipes throws exception because we do not expect grouped data
 471          $data = $path->apply_recipes($data);
 472      }
 473  
 474      /**
 475       * @expectedException convert_path_exception
 476       */
 477      public function test_grouped_convert_path_with_recipes() {
 478          // prepare some grouped data
 479          $data = array(
 480              'ID' => 77,
 481              'NAME' => 'Pale lagers',
 482              'BEERS' => array(
 483                  array(
 484                      'BEER' => array(
 485                          'ID' => 67,
 486                          'NAME' => 'Pilsner Urquell',
 487                      )
 488                  ),
 489                  array(
 490                      'BEER' => array(
 491                          'ID' => 34,
 492                          'NAME' => 'Heineken',
 493                      )
 494                  ),
 495              )
 496          );
 497  
 498          // implict recipes work for grouped data if the path is declared as grouped
 499          $path = new convert_path('beer_style', '/ROOT/BEER_STYLES/BEER_STYLE', array(), true);
 500          $data = $path->apply_recipes($data);
 501          $this->assertEquals('Heineken', $data['beers'][1]['beer']['name']);
 502  
 503          // an attempt to provide explicit recipes on grouped elements throws exception
 504          $path = new convert_path(
 505              'beer_style', '/ROOT/BEER_STYLES/BEER_STYLE',
 506              array(
 507                  'renamefields' => array(
 508                      'name' => 'beername',   // note this is confusing recipe because the 'name' is used for both
 509                      // beer-style name ('Pale lagers') and beer name ('Pilsner Urquell')
 510                  )
 511              ), true);
 512      }
 513  
 514      public function test_referenced_course_files() {
 515  
 516          $text = 'This is a text containing links to file.php
 517  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 />
 518      <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
 519      <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>
 520      <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />';
 521  
 522          $files = moodle1_converter::find_referenced_files($text);
 523          $this->assertEquals(gettype($files), 'array');
 524          $this->assertEquals(2, count($files));
 525          $this->assertTrue(in_array('/pics/news.gif', $files));
 526          $this->assertTrue(in_array('/MANUAL.DOC', $files));
 527  
 528          $text = moodle1_converter::rewrite_filephp_usage($text, array('/pics/news.gif', '/another/file/notused.txt'));
 529          $this->assertEquals($text, 'This is a text containing links to file.php
 530  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 />
 531      <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
 532      <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>
 533      <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />');
 534      }
 535  
 536      public function test_referenced_files_urlencoded() {
 537  
 538          $text = 'This is a text containing links to file.php
 539  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 />
 540      <br /><a href=\'$@FILEPHP@$$@SLASH@$pics$@SLASH@$news%20with%20spaces.gif$@FORCEDOWNLOAD@$\'>with urlencoded spaces</a><br />
 541  <a href="$@FILEPHP@$$@SLASH@$illegal%20pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (space and plus encoded)</a>
 542  <a href="$@FILEPHP@$$@SLASH@$illegal pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (none encoded)</a>
 543  <a href="$@FILEPHP@$$@SLASH@$illegal%20pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (only space encoded)</a>
 544  <a href="$@FILEPHP@$$@SLASH@$illegal pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (only plus)</a>';
 545  
 546          $files = moodle1_converter::find_referenced_files($text);
 547          $this->assertEquals(gettype($files), 'array');
 548          $this->assertEquals(3, count($files));
 549          $this->assertTrue(in_array('/pics/news.gif', $files));
 550          $this->assertTrue(in_array('/pics/news with spaces.gif', $files));
 551          $this->assertTrue(in_array('/illegal pics+movies/romeo+juliet.avi', $files));
 552  
 553          $text = moodle1_converter::rewrite_filephp_usage($text, $files);
 554          $this->assertEquals('This is a text containing links to file.php
 555  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 />
 556      <br /><a href=\'@@PLUGINFILE@@/pics/news%20with%20spaces.gif?forcedownload=1\'>with urlencoded spaces</a><br />
 557  <a href="@@PLUGINFILE@@/illegal%20pics%2Bmovies/romeo%2Bjuliet.avi">Download the full AVI for free! (space and plus encoded)</a>
 558  <a href="@@PLUGINFILE@@/illegal%20pics%2Bmovies/romeo%2Bjuliet.avi">Download the full AVI for free! (none encoded)</a>
 559  <a href="$@FILEPHP@$$@SLASH@$illegal%20pics+movies$@SLASH@$romeo+juliet.avi">Download the full AVI for free! (only space encoded)</a>
 560  <a href="$@FILEPHP@$$@SLASH@$illegal pics%2Bmovies$@SLASH@$romeo%2Bjuliet.avi">Download the full AVI for free! (only plus)</a>', $text);
 561      }
 562  
 563      public function test_question_bank_conversion() {
 564          global $CFG;
 565  
 566          $this->resetAfterTest(true);
 567  
 568          copy(
 569              "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/questions.xml",
 570              "$this->tempdirpath/moodle.xml"
 571          );
 572          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 573          $converter->convert();
 574      }
 575  
 576      public function test_convert_run_convert() {
 577          $this->resetAfterTest(true);
 578          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 579          $converter->convert();
 580      }
 581  
 582      public function test_inforef_manager() {
 583          $converter = convert_factory::get_converter('moodle1', $this->tempdir);
 584          $inforef = $converter->get_inforef_manager('unittest');
 585          $inforef->add_ref('file', 45);
 586          $inforef->add_refs('file', array(46, 47));
 587          // todo test the write_refs() via some dummy xml_writer
 588          $this->expectException('coding_exception');
 589          $inforef->add_ref('unknown_referenced_item_name', 76);
 590      }
 591  }