See Release Notes
Long Term Support Release
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 /lib/filestorage/file_storage.php 19 * 20 * @package core_files 21 * @category phpunit 22 * @copyright 2012 David Mudrak <david@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->libdir . '/filelib.php'); 30 require_once($CFG->dirroot . '/repository/lib.php'); 31 require_once($CFG->libdir . '/filestorage/stored_file.php'); 32 33 /** 34 * Unit tests for /lib/filestorage/file_storage.php 35 * 36 * @copyright 2012 David Mudrak <david@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 * @coversDefaultClass \file_storage 39 */ 40 class core_files_file_storage_testcase extends advanced_testcase { 41 42 /** 43 * Files can be created from strings. 44 * 45 * @covers ::create_file_from_string 46 */ 47 public function test_create_file_from_string() { 48 global $DB; 49 50 $this->resetAfterTest(true); 51 52 // Number of files installed in the database on a fresh Moodle site. 53 $installedfiles = $DB->count_records('files', array()); 54 55 $content = 'abcd'; 56 $syscontext = context_system::instance(); 57 $filerecord = array( 58 'contextid' => $syscontext->id, 59 'component' => 'core', 60 'filearea' => 'unittest', 61 'itemid' => 0, 62 'filepath' => '/images/', 63 'filename' => 'testfile.txt', 64 ); 65 $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']); 66 67 $fs = get_file_storage(); 68 $file = $fs->create_file_from_string($filerecord, $content); 69 70 $this->assertInstanceOf('stored_file', $file); 71 $this->assertTrue($file->compare_to_string($content)); 72 $this->assertSame($pathhash, $file->get_pathnamehash()); 73 74 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>$pathhash))); 75 76 $filesystem = $fs->get_file_system(); 77 $location = $filesystem->get_local_path_from_storedfile($file, true); 78 79 $this->assertFileExists($location); 80 81 // Verify the dir placeholder files are created. 82 $this->assertEquals($installedfiles + 3, $DB->count_records('files', array())); 83 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].'/.')))); 84 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].'.')))); 85 86 // Tests that missing content file is recreated. 87 88 unlink($location); 89 $this->assertFileNotExists($location); 90 91 $filerecord['filename'] = 'testfile2.txt'; 92 $file2 = $fs->create_file_from_string($filerecord, $content); 93 $this->assertInstanceOf('stored_file', $file2); 94 $this->assertSame($file->get_contenthash(), $file2->get_contenthash()); 95 $this->assertFileExists($location); 96 97 $this->assertEquals($installedfiles + 4, $DB->count_records('files', array())); 98 99 // Test that borked content file is recreated. 100 101 $this->assertSame(2, file_put_contents($location, 'xx')); 102 103 $filerecord['filename'] = 'testfile3.txt'; 104 $file3 = $fs->create_file_from_string($filerecord, $content); 105 $this->assertInstanceOf('stored_file', $file3); 106 $this->assertSame($file->get_contenthash(), $file3->get_contenthash()); 107 $this->assertFileExists($location); 108 109 $this->assertSame($content, file_get_contents($location)); 110 $this->assertDebuggingCalled(); 111 112 $this->assertEquals($installedfiles + 5, $DB->count_records('files', array())); 113 } 114 115 /** 116 * Local files can be added to the filepool 117 * 118 * @covers ::create_file_from_pathname 119 */ 120 public function test_create_file_from_pathname() { 121 global $CFG, $DB; 122 123 $this->resetAfterTest(true); 124 125 // Number of files installed in the database on a fresh Moodle site. 126 $installedfiles = $DB->count_records('files', array()); 127 128 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 129 $syscontext = context_system::instance(); 130 $filerecord = array( 131 'contextid' => $syscontext->id, 132 'component' => 'core', 133 'filearea' => 'unittest', 134 'itemid' => 0, 135 'filepath' => '/images/', 136 'filename' => 'testimage.jpg', 137 ); 138 $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']); 139 140 $fs = get_file_storage(); 141 $file = $fs->create_file_from_pathname($filerecord, $filepath); 142 143 $this->assertInstanceOf('stored_file', $file); 144 $this->assertTrue($file->compare_to_path($filepath)); 145 146 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>$pathhash))); 147 148 $filesystem = $fs->get_file_system(); 149 $location = $filesystem->get_local_path_from_storedfile($file, true); 150 151 $this->assertFileExists($location); 152 153 // Verify the dir placeholder files are created. 154 $this->assertEquals($installedfiles + 3, $DB->count_records('files', array())); 155 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].'/.')))); 156 $this->assertTrue($DB->record_exists('files', array('pathnamehash'=>sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].'.')))); 157 158 // Tests that missing content file is recreated. 159 160 unlink($location); 161 $this->assertFileNotExists($location); 162 163 $filerecord['filename'] = 'testfile2.jpg'; 164 $file2 = $fs->create_file_from_pathname($filerecord, $filepath); 165 $this->assertInstanceOf('stored_file', $file2); 166 $this->assertSame($file->get_contenthash(), $file2->get_contenthash()); 167 $this->assertFileExists($location); 168 169 $this->assertEquals($installedfiles + 4, $DB->count_records('files', array())); 170 171 // Test that borked content file is recreated. 172 173 $this->assertSame(2, file_put_contents($location, 'xx')); 174 175 $filerecord['filename'] = 'testfile3.jpg'; 176 $file3 = $fs->create_file_from_pathname($filerecord, $filepath); 177 $this->assertInstanceOf('stored_file', $file3); 178 $this->assertSame($file->get_contenthash(), $file3->get_contenthash()); 179 $this->assertFileExists($location); 180 181 $this->assertSame(file_get_contents($filepath), file_get_contents($location)); 182 $this->assertDebuggingCalled(); 183 184 $this->assertEquals($installedfiles + 5, $DB->count_records('files', array())); 185 186 // Test invalid file creation. 187 188 $filerecord['filename'] = 'testfile4.jpg'; 189 try { 190 $fs->create_file_from_pathname($filerecord, $filepath.'nonexistent'); 191 $this->fail('Exception expected when trying to add non-existent stored file.'); 192 } catch (Exception $e) { 193 $this->assertInstanceOf('file_exception', $e); 194 } 195 } 196 197 /** 198 * Tests get get file. 199 * 200 * @covers ::get_file 201 */ 202 public function test_get_file() { 203 global $CFG; 204 205 $this->resetAfterTest(false); 206 207 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 208 $syscontext = context_system::instance(); 209 $filerecord = array( 210 'contextid' => $syscontext->id, 211 'component' => 'core', 212 'filearea' => 'unittest', 213 'itemid' => 0, 214 'filepath' => '/images/', 215 'filename' => 'testimage.jpg', 216 ); 217 $pathhash = sha1('/'.$filerecord['contextid'].'/'.$filerecord['component'].'/'.$filerecord['filearea'].'/'.$filerecord['itemid'].$filerecord['filepath'].$filerecord['filename']); 218 219 $fs = get_file_storage(); 220 $file = $fs->create_file_from_pathname($filerecord, $filepath); 221 222 $this->assertInstanceOf('stored_file', $file); 223 $this->assertEquals($syscontext->id, $file->get_contextid()); 224 $this->assertEquals('core', $file->get_component()); 225 $this->assertEquals('unittest', $file->get_filearea()); 226 $this->assertEquals(0, $file->get_itemid()); 227 $this->assertEquals('/images/', $file->get_filepath()); 228 $this->assertEquals('testimage.jpg', $file->get_filename()); 229 $this->assertEquals(filesize($filepath), $file->get_filesize()); 230 $this->assertEquals($pathhash, $file->get_pathnamehash()); 231 232 return $file; 233 } 234 235 /** 236 * Local images can be added to the filepool and their preview can be obtained 237 * 238 * @param stored_file $file 239 * @depends test_get_file 240 * @covers ::get_file_preview 241 */ 242 public function test_get_file_preview(stored_file $file) { 243 global $CFG; 244 245 $this->resetAfterTest(); 246 $fs = get_file_storage(); 247 248 $previewtinyicon = $fs->get_file_preview($file, 'tinyicon'); 249 $this->assertInstanceOf('stored_file', $previewtinyicon); 250 $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename()); 251 252 $previewtinyicon = $fs->get_file_preview($file, 'thumb'); 253 $this->assertInstanceOf('stored_file', $previewtinyicon); 254 $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename()); 255 256 $this->expectException('file_exception'); 257 $fs->get_file_preview($file, 'amodewhichdoesntexist'); 258 } 259 260 /** 261 * Tests for get_file_preview without an image. 262 * 263 * @covers ::get_file_preview 264 */ 265 public function test_get_file_preview_nonimage() { 266 $this->resetAfterTest(true); 267 $syscontext = context_system::instance(); 268 $filerecord = array( 269 'contextid' => $syscontext->id, 270 'component' => 'core', 271 'filearea' => 'unittest', 272 'itemid' => 0, 273 'filepath' => '/textfiles/', 274 'filename' => 'testtext.txt', 275 ); 276 277 $fs = get_file_storage(); 278 $fs->create_file_from_string($filerecord, 'text contents'); 279 $textfile = $fs->get_file($syscontext->id, $filerecord['component'], $filerecord['filearea'], 280 $filerecord['itemid'], $filerecord['filepath'], $filerecord['filename']); 281 282 $preview = $fs->get_file_preview($textfile, 'thumb'); 283 $this->assertFalse($preview); 284 } 285 286 /** 287 * Make sure renaming is working 288 * 289 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org} 290 * @covers \stored_file::rename 291 */ 292 public function test_file_renaming() { 293 global $CFG; 294 295 $this->resetAfterTest(); 296 $fs = get_file_storage(); 297 $syscontext = context_system::instance(); 298 $component = 'core'; 299 $filearea = 'unittest'; 300 $itemid = 0; 301 $filepath = '/'; 302 $filename = 'test.txt'; 303 304 $filerecord = array( 305 'contextid' => $syscontext->id, 306 'component' => $component, 307 'filearea' => $filearea, 308 'itemid' => $itemid, 309 'filepath' => $filepath, 310 'filename' => $filename, 311 ); 312 313 $originalfile = $fs->create_file_from_string($filerecord, 'Test content'); 314 $this->assertInstanceOf('stored_file', $originalfile); 315 $contenthash = $originalfile->get_contenthash(); 316 $newpath = '/test/'; 317 $newname = 'newtest.txt'; 318 319 // This should work. 320 $originalfile->rename($newpath, $newname); 321 $file = $fs->get_file($syscontext->id, $component, $filearea, $itemid, $newpath, $newname); 322 $this->assertInstanceOf('stored_file', $file); 323 $this->assertEquals($contenthash, $file->get_contenthash()); 324 325 // Try break it. 326 $this->expectException('file_exception'); 327 $this->expectExceptionMessage('Cannot create file 1/core/unittest/0/test/newtest.txt (file exists, cannot rename)'); 328 // This shall throw exception. 329 $originalfile->rename($newpath, $newname); 330 } 331 332 /** 333 * Create file from reference tests 334 * 335 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org} 336 * @covers ::create_file_from_reference 337 */ 338 public function test_create_file_from_reference() { 339 global $CFG, $DB; 340 341 $this->resetAfterTest(); 342 // Create user. 343 $generator = $this->getDataGenerator(); 344 $user = $generator->create_user(); 345 $this->setUser($user); 346 $usercontext = context_user::instance($user->id); 347 $syscontext = context_system::instance(); 348 349 $fs = get_file_storage(); 350 351 $repositorypluginname = 'user'; 352 // Override repository permission. 353 $capability = 'repository/' . $repositorypluginname . ':view'; 354 $guestroleid = $DB->get_field('role', 'id', array('shortname' => 'guest')); 355 assign_capability($capability, CAP_ALLOW, $guestroleid, $syscontext->id, true); 356 357 $args = array(); 358 $args['type'] = $repositorypluginname; 359 $repos = repository::get_instances($args); 360 $userrepository = reset($repos); 361 $this->assertInstanceOf('repository', $userrepository); 362 363 $component = 'user'; 364 $filearea = 'private'; 365 $itemid = 0; 366 $filepath = '/'; 367 $filename = 'userfile.txt'; 368 369 $filerecord = array( 370 'contextid' => $usercontext->id, 371 'component' => $component, 372 'filearea' => $filearea, 373 'itemid' => $itemid, 374 'filepath' => $filepath, 375 'filename' => $filename, 376 ); 377 378 $content = 'Test content'; 379 $originalfile = $fs->create_file_from_string($filerecord, $content); 380 $this->assertInstanceOf('stored_file', $originalfile); 381 382 $newfilerecord = array( 383 'contextid' => $syscontext->id, 384 'component' => 'core', 385 'filearea' => 'phpunit', 386 'itemid' => 0, 387 'filepath' => $filepath, 388 'filename' => $filename, 389 ); 390 $ref = $fs->pack_reference($filerecord); 391 $newstoredfile = $fs->create_file_from_reference($newfilerecord, $userrepository->id, $ref); 392 $this->assertInstanceOf('stored_file', $newstoredfile); 393 $this->assertEquals($userrepository->id, $newstoredfile->get_repository_id()); 394 $this->assertEquals($originalfile->get_contenthash(), $newstoredfile->get_contenthash()); 395 $this->assertEquals($originalfile->get_filesize(), $newstoredfile->get_filesize()); 396 $this->assertRegExp('#' . $filename. '$#', $newstoredfile->get_reference_details()); 397 398 // Test looking for references. 399 $count = $fs->get_references_count_by_storedfile($originalfile); 400 $this->assertEquals(1, $count); 401 $files = $fs->get_references_by_storedfile($originalfile); 402 $file = reset($files); 403 $this->assertEquals($file, $newstoredfile); 404 405 // Look for references by repository ID. 406 $files = $fs->get_external_files($userrepository->id); 407 $file = reset($files); 408 $this->assertEquals($file, $newstoredfile); 409 410 // Try convert reference to local file. 411 $importedfile = $fs->import_external_file($newstoredfile); 412 $this->assertFalse($importedfile->is_external_file()); 413 $this->assertInstanceOf('stored_file', $importedfile); 414 // Still readable? 415 $this->assertEquals($content, $importedfile->get_content()); 416 } 417 418 /** 419 * Create file from reference tests 420 * 421 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org} 422 * @covers ::create_file_from_reference 423 */ 424 public function test_create_file_from_reference_with_content_hash() { 425 global $CFG, $DB; 426 427 $this->resetAfterTest(); 428 // Create user. 429 $generator = $this->getDataGenerator(); 430 $user = $generator->create_user(); 431 $this->setUser($user); 432 $usercontext = context_user::instance($user->id); 433 $syscontext = context_system::instance(); 434 435 $fs = get_file_storage(); 436 437 $repositorypluginname = 'user'; 438 // Override repository permission. 439 $capability = 'repository/' . $repositorypluginname . ':view'; 440 $guestroleid = $DB->get_field('role', 'id', array('shortname' => 'guest')); 441 assign_capability($capability, CAP_ALLOW, $guestroleid, $syscontext->id, true); 442 443 $args = array(); 444 $args['type'] = $repositorypluginname; 445 $repos = repository::get_instances($args); 446 $userrepository = reset($repos); 447 $this->assertInstanceOf('repository', $userrepository); 448 449 $component = 'user'; 450 $filearea = 'private'; 451 $itemid = 0; 452 $filepath = '/'; 453 $filename = 'userfile.txt'; 454 455 $filerecord = array( 456 'contextid' => $usercontext->id, 457 'component' => $component, 458 'filearea' => $filearea, 459 'itemid' => $itemid, 460 'filepath' => $filepath, 461 'filename' => $filename, 462 ); 463 464 $content = 'Test content'; 465 $originalfile = $fs->create_file_from_string($filerecord, $content); 466 $this->assertInstanceOf('stored_file', $originalfile); 467 468 $otherfilerecord = $filerecord; 469 $otherfilerecord['filename'] = 'other-filename.txt'; 470 $otherfilewithsamecontents = $fs->create_file_from_string($otherfilerecord, $content); 471 $this->assertInstanceOf('stored_file', $otherfilewithsamecontents); 472 473 $newfilerecord = array( 474 'contextid' => $syscontext->id, 475 'component' => 'core', 476 'filearea' => 'phpunit', 477 'itemid' => 0, 478 'filepath' => $filepath, 479 'filename' => $filename, 480 'contenthash' => $originalfile->get_contenthash(), 481 ); 482 $ref = $fs->pack_reference($filerecord); 483 $newstoredfile = $fs->create_file_from_reference($newfilerecord, $userrepository->id, $ref); 484 $this->assertInstanceOf('stored_file', $newstoredfile); 485 $this->assertEquals($userrepository->id, $newstoredfile->get_repository_id()); 486 $this->assertEquals($originalfile->get_contenthash(), $newstoredfile->get_contenthash()); 487 $this->assertEquals($originalfile->get_filesize(), $newstoredfile->get_filesize()); 488 $this->assertRegExp('#' . $filename . '$#', $newstoredfile->get_reference_details()); 489 } 490 491 private function setup_three_private_files() { 492 493 $this->resetAfterTest(); 494 495 $generator = $this->getDataGenerator(); 496 $user = $generator->create_user(); 497 $this->setUser($user->id); 498 $usercontext = context_user::instance($user->id); 499 // Create a user private file. 500 $file1 = new stdClass; 501 $file1->contextid = $usercontext->id; 502 $file1->component = 'user'; 503 $file1->filearea = 'private'; 504 $file1->itemid = 0; 505 $file1->filepath = '/'; 506 $file1->filename = '1.txt'; 507 $file1->source = 'test'; 508 509 $fs = get_file_storage(); 510 $userfile1 = $fs->create_file_from_string($file1, 'file1 content'); 511 $this->assertInstanceOf('stored_file', $userfile1); 512 513 $file2 = clone($file1); 514 $file2->filename = '2.txt'; 515 $userfile2 = $fs->create_file_from_string($file2, 'file2 content longer'); 516 $this->assertInstanceOf('stored_file', $userfile2); 517 518 $file3 = clone($file1); 519 $file3->filename = '3.txt'; 520 $userfile3 = $fs->create_file_from_storedfile($file3, $userfile2); 521 $this->assertInstanceOf('stored_file', $userfile3); 522 523 $user->ctxid = $usercontext->id; 524 525 return $user; 526 } 527 528 /** 529 * Tests for get_area_files 530 * 531 * @covers ::get_area_files 532 */ 533 public function test_get_area_files() { 534 $user = $this->setup_three_private_files(); 535 $fs = get_file_storage(); 536 537 // Get area files with default options. 538 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 539 540 // Should be the two files we added plus the folder. 541 $this->assertEquals(4, count($areafiles)); 542 543 // Verify structure. 544 foreach ($areafiles as $key => $file) { 545 $this->assertInstanceOf('stored_file', $file); 546 $this->assertEquals($key, $file->get_pathnamehash()); 547 } 548 549 // Get area files without a folder. 550 $folderlessfiles = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'sortorder', false); 551 // Should be the two files without folder. 552 $this->assertEquals(3, count($folderlessfiles)); 553 554 // Verify structure. 555 foreach ($folderlessfiles as $key => $file) { 556 $this->assertInstanceOf('stored_file', $file); 557 $this->assertEquals($key, $file->get_pathnamehash()); 558 } 559 560 // Get area files ordered by id. 561 $filesbyid = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'id', false); 562 // Should be the two files without folder. 563 $this->assertEquals(3, count($filesbyid)); 564 565 // Verify structure. 566 foreach ($filesbyid as $key => $file) { 567 $this->assertInstanceOf('stored_file', $file); 568 $this->assertEquals($key, $file->get_pathnamehash()); 569 } 570 571 // Test the limit feature to retrieve each individual file. 572 $limited = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'filename', false, 573 0, 0, 1); 574 $mapfunc = function($f) { 575 return $f->get_filename(); 576 }; 577 $this->assertEquals(array('1.txt'), array_values(array_map($mapfunc, $limited))); 578 $limited = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'filename', false, 579 0, 1, 50); 580 $this->assertEquals(array('2.txt', '3.txt'), array_values(array_map($mapfunc, $limited))); 581 582 // Test with an itemid with no files. 583 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private', 666, 'sortorder', false); 584 // Should be none. 585 $this->assertEmpty($areafiles); 586 } 587 588 /** 589 * Tests for get_area_tree 590 * 591 * @covers ::get_area_tree 592 */ 593 public function test_get_area_tree() { 594 $user = $this->setup_three_private_files(); 595 $fs = get_file_storage(); 596 597 // Get area files with default options. 598 $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0); 599 $this->assertEmpty($areatree['subdirs']); 600 $this->assertNotEmpty($areatree['files']); 601 $this->assertCount(3, $areatree['files']); 602 603 // Ensure an empty try with a fake itemid. 604 $emptytree = $fs->get_area_tree($user->ctxid, 'user', 'private', 666); 605 $this->assertEmpty($emptytree['subdirs']); 606 $this->assertEmpty($emptytree['files']); 607 608 // Create a subdir. 609 $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/'); 610 $this->assertInstanceOf('stored_file', $dir); 611 612 // Add a file to the subdir. 613 $filerecord = array( 614 'contextid' => $user->ctxid, 615 'component' => 'user', 616 'filearea' => 'private', 617 'itemid' => 0, 618 'filepath' => '/testsubdir/', 619 'filename' => 'test-get-area-tree.txt', 620 ); 621 622 $directoryfile = $fs->create_file_from_string($filerecord, 'Test content'); 623 $this->assertInstanceOf('stored_file', $directoryfile); 624 625 $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0); 626 627 // At the top level there should still be 3 files. 628 $this->assertCount(3, $areatree['files']); 629 630 // There should now be a subdirectory. 631 $this->assertCount(1, $areatree['subdirs']); 632 633 // The test subdir is named testsubdir. 634 $subdir = $areatree['subdirs']['testsubdir']; 635 $this->assertNotEmpty($subdir); 636 // It should have one file we added. 637 $this->assertCount(1, $subdir['files']); 638 // And no subdirs itself. 639 $this->assertCount(0, $subdir['subdirs']); 640 641 // Verify the file is the one we added. 642 $subdirfile = reset($subdir['files']); 643 $this->assertInstanceOf('stored_file', $subdirfile); 644 $this->assertEquals($filerecord['filename'], $subdirfile->get_filename()); 645 } 646 647 /** 648 * Tests for get_file_by_id 649 * 650 * @covers ::get_file_by_id 651 */ 652 public function test_get_file_by_id() { 653 $user = $this->setup_three_private_files(); 654 $fs = get_file_storage(); 655 656 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 657 658 // Test get_file_by_id. 659 $filebyid = reset($areafiles); 660 $shouldbesame = $fs->get_file_by_id($filebyid->get_id()); 661 $this->assertEquals($filebyid->get_contenthash(), $shouldbesame->get_contenthash()); 662 663 // Test an id which doens't exist. 664 $doesntexist = $fs->get_file_by_id(99999); 665 $this->assertFalse($doesntexist); 666 } 667 668 /** 669 * Tests for get_file_by_hash 670 * 671 * @covers ::get_file_by_hash 672 */ 673 public function test_get_file_by_hash() { 674 $user = $this->setup_three_private_files(); 675 $fs = get_file_storage(); 676 677 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 678 // Test get_file_by_hash. 679 $filebyhash = reset($areafiles); 680 $shouldbesame = $fs->get_file_by_hash($filebyhash->get_pathnamehash()); 681 $this->assertEquals($filebyhash->get_id(), $shouldbesame->get_id()); 682 683 // Test an hash which doens't exist. 684 $doesntexist = $fs->get_file_by_hash('DOESNTEXIST'); 685 $this->assertFalse($doesntexist); 686 } 687 688 /** 689 * Tests for get_external_files 690 * 691 * @covers ::get_external_files 692 */ 693 public function test_get_external_files() { 694 $user = $this->setup_three_private_files(); 695 $fs = get_file_storage(); 696 697 $repos = repository::get_instances(array('type'=>'user')); 698 $userrepository = reset($repos); 699 $this->assertInstanceOf('repository', $userrepository); 700 701 // No aliases yet. 702 $exfiles = $fs->get_external_files($userrepository->id, 'id'); 703 $this->assertEquals(array(), $exfiles); 704 705 // Create three aliases linking the same original: $aliasfile1 and $aliasfile2 are 706 // created via create_file_from_reference(), $aliasfile3 created from $aliasfile2. 707 $originalfile = null; 708 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) { 709 if (!$areafile->is_directory()) { 710 $originalfile = $areafile; 711 break; 712 } 713 } 714 $this->assertInstanceOf('stored_file', $originalfile); 715 $originalrecord = array( 716 'contextid' => $originalfile->get_contextid(), 717 'component' => $originalfile->get_component(), 718 'filearea' => $originalfile->get_filearea(), 719 'itemid' => $originalfile->get_itemid(), 720 'filepath' => $originalfile->get_filepath(), 721 'filename' => $originalfile->get_filename(), 722 ); 723 724 $aliasrecord = $this->generate_file_record(); 725 $aliasrecord->filepath = '/foo/'; 726 $aliasrecord->filename = 'one.txt'; 727 728 $ref = $fs->pack_reference($originalrecord); 729 $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref); 730 731 $aliasrecord->filepath = '/bar/'; 732 $aliasrecord->filename = 'uno.txt'; 733 // Change the order of the items in the array to make sure that it does not matter. 734 ksort($originalrecord); 735 $ref = $fs->pack_reference($originalrecord); 736 $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref); 737 738 $aliasrecord->filepath = '/bar/'; 739 $aliasrecord->filename = 'jedna.txt'; 740 $aliasfile3 = $fs->create_file_from_storedfile($aliasrecord, $aliasfile2); 741 742 // Make sure we get three aliases now. 743 $exfiles = $fs->get_external_files($userrepository->id, 'id'); 744 $this->assertEquals(3, count($exfiles)); 745 foreach ($exfiles as $exfile) { 746 $this->assertTrue($exfile->is_external_file()); 747 } 748 // Make sure they all link the same original (thence that all are linked with the same 749 // record in {files_reference}). 750 $this->assertEquals($aliasfile1->get_referencefileid(), $aliasfile2->get_referencefileid()); 751 $this->assertEquals($aliasfile3->get_referencefileid(), $aliasfile2->get_referencefileid()); 752 } 753 754 /** 755 * Tests for create_directory with a negative contextid. 756 * 757 * @covers ::create_directory 758 */ 759 public function test_create_directory_contextid_negative() { 760 $fs = get_file_storage(); 761 762 $this->expectException('file_exception'); 763 $fs->create_directory(-1, 'core', 'unittest', 0, '/'); 764 } 765 766 /** 767 * Tests for create_directory with an invalid contextid. 768 * 769 * @covers ::create_directory 770 */ 771 public function test_create_directory_contextid_invalid() { 772 $fs = get_file_storage(); 773 774 $this->expectException('file_exception'); 775 $fs->create_directory('not an int', 'core', 'unittest', 0, '/'); 776 } 777 778 /** 779 * Tests for create_directory with an invalid component. 780 * 781 * @covers ::create_directory 782 */ 783 public function test_create_directory_component_invalid() { 784 $fs = get_file_storage(); 785 $syscontext = context_system::instance(); 786 787 $this->expectException('file_exception'); 788 $fs->create_directory($syscontext->id, 'bad/component', 'unittest', 0, '/'); 789 } 790 791 /** 792 * Tests for create_directory with an invalid filearea. 793 * 794 * @covers ::create_directory 795 */ 796 public function test_create_directory_filearea_invalid() { 797 $fs = get_file_storage(); 798 $syscontext = context_system::instance(); 799 800 $this->expectException('file_exception'); 801 $fs->create_directory($syscontext->id, 'core', 'bad-filearea', 0, '/'); 802 } 803 804 /** 805 * Tests for create_directory with a negative itemid 806 * 807 * @covers ::create_directory 808 */ 809 public function test_create_directory_itemid_negative() { 810 $fs = get_file_storage(); 811 $syscontext = context_system::instance(); 812 813 $this->expectException('file_exception'); 814 $fs->create_directory($syscontext->id, 'core', 'unittest', -1, '/'); 815 } 816 817 /** 818 * Tests for create_directory with an invalid itemid 819 * 820 * @covers ::create_directory 821 */ 822 public function test_create_directory_itemid_invalid() { 823 $fs = get_file_storage(); 824 $syscontext = context_system::instance(); 825 826 $this->expectException('file_exception'); 827 $fs->create_directory($syscontext->id, 'core', 'unittest', 'notanint', '/'); 828 } 829 830 /** 831 * Tests for create_directory with an invalid filepath 832 * 833 * @covers ::create_directory 834 */ 835 public function test_create_directory_filepath_invalid() { 836 $fs = get_file_storage(); 837 $syscontext = context_system::instance(); 838 839 $this->expectException('file_exception'); 840 $fs->create_directory($syscontext->id, 'core', 'unittest', 0, '/not-with-trailing/or-leading-slash'); 841 } 842 843 /** 844 * Tests for get_directory_files. 845 * 846 * @covers ::get_directory_files 847 */ 848 public function test_get_directory_files() { 849 $user = $this->setup_three_private_files(); 850 $fs = get_file_storage(); 851 852 $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/'); 853 $this->assertInstanceOf('stored_file', $dir); 854 855 // Add a file to the subdir. 856 $filerecord = array( 857 'contextid' => $user->ctxid, 858 'component' => 'user', 859 'filearea' => 'private', 860 'itemid' => 0, 861 'filepath' => '/testsubdir/', 862 'filename' => 'test-get-area-tree.txt', 863 ); 864 865 $directoryfile = $fs->create_file_from_string($filerecord, 'Test content'); 866 $this->assertInstanceOf('stored_file', $directoryfile); 867 868 // Don't recurse without dirs. 869 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, false, 'id'); 870 // 3 files only. 871 $this->assertCount(3, $files); 872 foreach ($files as $key => $file) { 873 $this->assertInstanceOf('stored_file', $file); 874 $this->assertEquals($key, $file->get_pathnamehash()); 875 } 876 877 // Don't recurse with dirs. 878 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, true, 'id'); 879 // 3 files + 1 directory. 880 $this->assertCount(4, $files); 881 foreach ($files as $key => $file) { 882 $this->assertInstanceOf('stored_file', $file); 883 $this->assertEquals($key, $file->get_pathnamehash()); 884 } 885 886 // Recurse with dirs. 887 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, true, 'id'); 888 // 3 files + 1 directory + 1 subdir file. 889 $this->assertCount(5, $files); 890 foreach ($files as $key => $file) { 891 $this->assertInstanceOf('stored_file', $file); 892 $this->assertEquals($key, $file->get_pathnamehash()); 893 } 894 895 // Recurse without dirs. 896 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, false, 'id'); 897 // 3 files + 1 subdir file. 898 $this->assertCount(4, $files); 899 foreach ($files as $key => $file) { 900 $this->assertInstanceOf('stored_file', $file); 901 $this->assertEquals($key, $file->get_pathnamehash()); 902 } 903 } 904 905 /** 906 * Tests for search_references. 907 * 908 * @covers ::search_references 909 */ 910 public function test_search_references() { 911 $user = $this->setup_three_private_files(); 912 $fs = get_file_storage(); 913 $repos = repository::get_instances(array('type'=>'user')); 914 $repo = reset($repos); 915 916 $alias1 = array( 917 'contextid' => $user->ctxid, 918 'component' => 'user', 919 'filearea' => 'private', 920 'itemid' => 0, 921 'filepath' => '/aliases/', 922 'filename' => 'alias-to-1.txt' 923 ); 924 925 $alias2 = array( 926 'contextid' => $user->ctxid, 927 'component' => 'user', 928 'filearea' => 'private', 929 'itemid' => 0, 930 'filepath' => '/aliases/', 931 'filename' => 'another-alias-to-1.txt' 932 ); 933 934 $reference = file_storage::pack_reference(array( 935 'contextid' => $user->ctxid, 936 'component' => 'user', 937 'filearea' => 'private', 938 'itemid' => 0, 939 'filepath' => '/', 940 'filename' => '1.txt' 941 )); 942 943 // There are no aliases now. 944 $result = $fs->search_references($reference); 945 $this->assertEquals(array(), $result); 946 947 $result = $fs->search_references_count($reference); 948 $this->assertSame($result, 0); 949 950 // Create two aliases and make sure they are returned. 951 $fs->create_file_from_reference($alias1, $repo->id, $reference); 952 $fs->create_file_from_reference($alias2, $repo->id, $reference); 953 954 $result = $fs->search_references($reference); 955 $this->assertTrue(is_array($result)); 956 $this->assertEquals(count($result), 2); 957 foreach ($result as $alias) { 958 $this->assertTrue($alias instanceof stored_file); 959 } 960 961 $result = $fs->search_references_count($reference); 962 $this->assertSame($result, 2); 963 964 // The method can't be used for references to files outside the filepool. 965 $exceptionthrown = false; 966 try { 967 $fs->search_references('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg'); 968 } catch (file_reference_exception $e) { 969 $exceptionthrown = true; 970 } 971 $this->assertTrue($exceptionthrown); 972 973 $exceptionthrown = false; 974 try { 975 $fs->search_references_count('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg'); 976 } catch (file_reference_exception $e) { 977 $exceptionthrown = true; 978 } 979 $this->assertTrue($exceptionthrown); 980 } 981 982 /** 983 * Tests for delete_area_files. 984 * 985 * @covers ::delete_area_files 986 */ 987 public function test_delete_area_files() { 988 $user = $this->setup_three_private_files(); 989 $fs = get_file_storage(); 990 991 // Get area files with default options. 992 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 993 // Should be the two files we added plus the folder. 994 $this->assertEquals(4, count($areafiles)); 995 $fs->delete_area_files($user->ctxid, 'user', 'private'); 996 997 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 998 // Should be the two files we added plus the folder. 999 $this->assertEquals(0, count($areafiles)); 1000 } 1001 1002 /** 1003 * Tests for delete_area_files using an itemid. 1004 * 1005 * @covers ::delete_area_files 1006 */ 1007 public function test_delete_area_files_itemid() { 1008 $user = $this->setup_three_private_files(); 1009 $fs = get_file_storage(); 1010 1011 // Get area files with default options. 1012 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1013 // Should be the two files we added plus the folder. 1014 $this->assertEquals(4, count($areafiles)); 1015 $fs->delete_area_files($user->ctxid, 'user', 'private', 9999); 1016 1017 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1018 $this->assertEquals(4, count($areafiles)); 1019 } 1020 1021 /** 1022 * Tests for delete_area_files_select. 1023 * 1024 * @covers ::delete_area_files_select 1025 */ 1026 public function test_delete_area_files_select() { 1027 $user = $this->setup_three_private_files(); 1028 $fs = get_file_storage(); 1029 1030 // Get area files with default options. 1031 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1032 // Should be the two files we added plus the folder. 1033 $this->assertEquals(4, count($areafiles)); 1034 $fs->delete_area_files_select($user->ctxid, 'user', 'private', '!= :notitemid', array('notitemid'=>9999)); 1035 1036 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1037 // Should be the two files we added plus the folder. 1038 $this->assertEquals(0, count($areafiles)); 1039 } 1040 1041 /** 1042 * Tests for delete_component_files. 1043 * 1044 * @covers ::delete_component_files 1045 */ 1046 public function test_delete_component_files() { 1047 $user = $this->setup_three_private_files(); 1048 $fs = get_file_storage(); 1049 1050 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1051 $this->assertEquals(4, count($areafiles)); 1052 $fs->delete_component_files('user'); 1053 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private'); 1054 $this->assertEquals(0, count($areafiles)); 1055 } 1056 1057 /** 1058 * Tests for create_file_from_url. 1059 * 1060 * @covers ::create_file_from_url 1061 */ 1062 public function test_create_file_from_url() { 1063 $this->resetAfterTest(true); 1064 1065 $syscontext = context_system::instance(); 1066 $filerecord = array( 1067 'contextid' => $syscontext->id, 1068 'component' => 'core', 1069 'filearea' => 'unittest', 1070 'itemid' => 0, 1071 'filepath' => '/downloadtest/', 1072 ); 1073 $url = $this->getExternalTestFileUrl('/test.html'); 1074 1075 $fs = get_file_storage(); 1076 1077 // Test creating file without filename. 1078 $file1 = $fs->create_file_from_url($filerecord, $url); 1079 $this->assertInstanceOf('stored_file', $file1); 1080 1081 // Set filename. 1082 $filerecord['filename'] = 'unit-test-filename.html'; 1083 $file2 = $fs->create_file_from_url($filerecord, $url); 1084 $this->assertInstanceOf('stored_file', $file2); 1085 1086 // Use temporary file. 1087 $filerecord['filename'] = 'unit-test-with-temp-file.html'; 1088 $file3 = $fs->create_file_from_url($filerecord, $url, null, true); 1089 $file3 = $this->assertInstanceOf('stored_file', $file3); 1090 } 1091 1092 /** 1093 * Tests for cron. 1094 * 1095 * @covers ::cron 1096 */ 1097 public function test_cron() { 1098 $this->resetAfterTest(true); 1099 1100 // Note: this is only testing DB compatibility atm, rather than 1101 // that work is done. 1102 $fs = get_file_storage(); 1103 1104 $this->expectOutputRegex('/Cleaning up/'); 1105 $fs->cron(); 1106 } 1107 1108 /** 1109 * Tests for is_area_empty. 1110 * 1111 * @covers ::is_area_empty 1112 */ 1113 public function test_is_area_empty() { 1114 $user = $this->setup_three_private_files(); 1115 $fs = get_file_storage(); 1116 1117 $this->assertFalse($fs->is_area_empty($user->ctxid, 'user', 'private')); 1118 1119 // File area with madeup itemid should be empty. 1120 $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999)); 1121 // Still empty with dirs included. 1122 $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999, false)); 1123 } 1124 1125 /** 1126 * Tests for move_area_files_to_new_context. 1127 * 1128 * @covers ::move_area_files_to_new_context 1129 */ 1130 public function test_move_area_files_to_new_context() { 1131 $this->resetAfterTest(true); 1132 1133 // Create a course with a page resource. 1134 $course = $this->getDataGenerator()->create_course(); 1135 $page1 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); 1136 $page1context = context_module::instance($page1->cmid); 1137 1138 // Add a file to the page. 1139 $fs = get_file_storage(); 1140 $filerecord = array( 1141 'contextid' => $page1context->id, 1142 'component' => 'mod_page', 1143 'filearea' => 'content', 1144 'itemid' => 0, 1145 'filepath' => '/', 1146 'filename' => 'unit-test-file.txt', 1147 ); 1148 1149 $originalfile = $fs->create_file_from_string($filerecord, 'Test content'); 1150 $this->assertInstanceOf('stored_file', $originalfile); 1151 1152 $pagefiles = $fs->get_area_files($page1context->id, 'mod_page', 'content', 0, 'sortorder', false); 1153 // Should be one file in filearea. 1154 $this->assertFalse($fs->is_area_empty($page1context->id, 'mod_page', 'content')); 1155 1156 // Create a new page. 1157 $page2 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); 1158 $page2context = context_module::instance($page2->cmid); 1159 1160 // Newly created page area is empty. 1161 $this->assertTrue($fs->is_area_empty($page2context->id, 'mod_page', 'content')); 1162 1163 // Move the files. 1164 $fs->move_area_files_to_new_context($page1context->id, $page2context->id, 'mod_page', 'content'); 1165 1166 // Page2 filearea should no longer be empty. 1167 $this->assertFalse($fs->is_area_empty($page2context->id, 'mod_page', 'content')); 1168 1169 // Page1 filearea should now be empty. 1170 $this->assertTrue($fs->is_area_empty($page1context->id, 'mod_page', 'content')); 1171 1172 $page2files = $fs->get_area_files($page2context->id, 'mod_page', 'content', 0, 'sortorder', false); 1173 $movedfile = reset($page2files); 1174 1175 // The two files should have the same content hash. 1176 $this->assertEquals($movedfile->get_contenthash(), $originalfile->get_contenthash()); 1177 } 1178 1179 /** 1180 * Tests for convert_image. 1181 * 1182 * @covers ::convert_image 1183 */ 1184 public function test_convert_image() { 1185 global $CFG; 1186 1187 $this->resetAfterTest(false); 1188 1189 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1190 $syscontext = context_system::instance(); 1191 $filerecord = array( 1192 'contextid' => $syscontext->id, 1193 'component' => 'core', 1194 'filearea' => 'unittest', 1195 'itemid' => 0, 1196 'filepath' => '/images/', 1197 'filename' => 'testimage.jpg', 1198 ); 1199 1200 $fs = get_file_storage(); 1201 $original = $fs->create_file_from_pathname($filerecord, $filepath); 1202 1203 $filerecord['filename'] = 'testimage-converted-10x10.jpg'; 1204 $converted = $fs->convert_image($filerecord, $original, 10, 10, true, 100); 1205 $this->assertInstanceOf('stored_file', $converted); 1206 1207 $filerecord['filename'] = 'testimage-convereted-nosize.jpg'; 1208 $converted = $fs->convert_image($filerecord, $original); 1209 $this->assertInstanceOf('stored_file', $converted); 1210 } 1211 1212 /** 1213 * Tests for convert_image with a PNG. 1214 * 1215 * @covers ::convert_image 1216 */ 1217 public function test_convert_image_png() { 1218 global $CFG; 1219 1220 $this->resetAfterTest(false); 1221 1222 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.png'; 1223 $syscontext = context_system::instance(); 1224 $filerecord = array( 1225 'contextid' => $syscontext->id, 1226 'component' => 'core', 1227 'filearea' => 'unittest', 1228 'itemid' => 0, 1229 'filepath' => '/images/', 1230 'filename' => 'testimage.png', 1231 ); 1232 1233 $fs = get_file_storage(); 1234 $original = $fs->create_file_from_pathname($filerecord, $filepath); 1235 1236 // Vanilla test. 1237 $filerecord['filename'] = 'testimage-converted-nosize.png'; 1238 $vanilla = $fs->convert_image($filerecord, $original); 1239 $this->assertInstanceOf('stored_file', $vanilla); 1240 // Assert that byte 25 has the ascii value 6 for PNG-24. 1241 $this->assertTrue(ord(substr($vanilla->get_content(), 25, 1)) == 6); 1242 1243 // 10x10 resize test; also testing for a ridiculous quality setting, which 1244 // we should if necessary scale to the 0 - 9 range. 1245 $filerecord['filename'] = 'testimage-converted-10x10.png'; 1246 $converted = $fs->convert_image($filerecord, $original, 10, 10, true, 100); 1247 $this->assertInstanceOf('stored_file', $converted); 1248 // Assert that byte 25 has the ascii value 6 for PNG-24. 1249 $this->assertTrue(ord(substr($converted->get_content(), 25, 1)) == 6); 1250 1251 // Transparency test. 1252 $filerecord['filename'] = 'testimage-converted-102x31.png'; 1253 $converted = $fs->convert_image($filerecord, $original, 102, 31, true, 9); 1254 $this->assertInstanceOf('stored_file', $converted); 1255 // Assert that byte 25 has the ascii value 6 for PNG-24. 1256 $this->assertTrue(ord(substr($converted->get_content(), 25, 1)) == 6); 1257 1258 $originalfile = imagecreatefromstring($original->get_content()); 1259 $convertedfile = imagecreatefromstring($converted->get_content()); 1260 $vanillafile = imagecreatefromstring($vanilla->get_content()); 1261 1262 $originalcolors = imagecolorsforindex($originalfile, imagecolorat($originalfile, 0, 0)); 1263 $convertedcolors = imagecolorsforindex($convertedfile, imagecolorat($convertedfile, 0, 0)); 1264 $vanillacolors = imagecolorsforindex($vanillafile, imagecolorat($vanillafile, 0, 0)); 1265 $this->assertEquals(count($originalcolors), 4); 1266 $this->assertEquals(count($convertedcolors), 4); 1267 $this->assertEquals(count($vanillacolors), 4); 1268 $this->assertEquals($originalcolors['red'], $convertedcolors['red']); 1269 $this->assertEquals($originalcolors['green'], $convertedcolors['green']); 1270 $this->assertEquals($originalcolors['blue'], $convertedcolors['blue']); 1271 $this->assertEquals($originalcolors['alpha'], $convertedcolors['alpha']); 1272 $this->assertEquals($originalcolors['red'], $vanillacolors['red']); 1273 $this->assertEquals($originalcolors['green'], $vanillacolors['green']); 1274 $this->assertEquals($originalcolors['blue'], $vanillacolors['blue']); 1275 $this->assertEquals($originalcolors['alpha'], $vanillacolors['alpha']); 1276 $this->assertEquals($originalcolors['alpha'], 127); 1277 1278 } 1279 1280 private function generate_file_record() { 1281 $syscontext = context_system::instance(); 1282 $filerecord = new stdClass(); 1283 $filerecord->contextid = $syscontext->id; 1284 $filerecord->component = 'core'; 1285 $filerecord->filearea = 'phpunit'; 1286 $filerecord->filepath = '/'; 1287 $filerecord->filename = 'testfile.txt'; 1288 $filerecord->itemid = 0; 1289 1290 return $filerecord; 1291 } 1292 1293 /** 1294 * @expectedException file_exception 1295 * @covers ::create_file_from_storedfile 1296 */ 1297 public function test_create_file_from_storedfile_file_invalid() { 1298 $this->resetAfterTest(true); 1299 1300 $filerecord = $this->generate_file_record(); 1301 1302 $fs = get_file_storage(); 1303 1304 // Create a file from a file id which doesn't exist. 1305 $fs->create_file_from_storedfile($filerecord, 9999); 1306 } 1307 1308 /** 1309 * @expectedException file_exception 1310 * @expectedExceptionMessage Invalid contextid 1311 * @covers ::create_file_from_storedfile 1312 */ 1313 public function test_create_file_from_storedfile_contextid_invalid() { 1314 $this->resetAfterTest(true); 1315 1316 $filerecord = $this->generate_file_record(); 1317 1318 $fs = get_file_storage(); 1319 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1320 $this->assertInstanceOf('stored_file', $file1); 1321 1322 $filerecord->filename = 'invalid.txt'; 1323 $filerecord->contextid = 'invalid'; 1324 1325 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1326 } 1327 1328 /** 1329 * @expectedException file_exception 1330 * @expectedExceptionMessage Invalid component 1331 * @covers ::create_file_from_storedfile 1332 */ 1333 public function test_create_file_from_storedfile_component_invalid() { 1334 $this->resetAfterTest(true); 1335 1336 $filerecord = $this->generate_file_record(); 1337 1338 $fs = get_file_storage(); 1339 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1340 $this->assertInstanceOf('stored_file', $file1); 1341 1342 $filerecord->filename = 'invalid.txt'; 1343 $filerecord->component = 'bad/component'; 1344 1345 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1346 } 1347 1348 /** 1349 * @expectedException file_exception 1350 * @expectedExceptionMessage Invalid filearea 1351 * @covers ::create_file_from_storedfile 1352 */ 1353 public function test_create_file_from_storedfile_filearea_invalid() { 1354 $this->resetAfterTest(true); 1355 1356 $filerecord = $this->generate_file_record(); 1357 1358 $fs = get_file_storage(); 1359 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1360 $this->assertInstanceOf('stored_file', $file1); 1361 1362 $filerecord->filename = 'invalid.txt'; 1363 $filerecord->filearea = 'bad-filearea'; 1364 1365 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1366 } 1367 1368 /** 1369 * @expectedException file_exception 1370 * @expectedExceptionMessage Invalid itemid 1371 * @covers ::create_file_from_storedfile 1372 */ 1373 public function test_create_file_from_storedfile_itemid_invalid() { 1374 $this->resetAfterTest(true); 1375 1376 $filerecord = $this->generate_file_record(); 1377 1378 $fs = get_file_storage(); 1379 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1380 $this->assertInstanceOf('stored_file', $file1); 1381 1382 $filerecord->filename = 'invalid.txt'; 1383 $filerecord->itemid = 'bad-itemid'; 1384 1385 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1386 } 1387 1388 /** 1389 * @expectedException file_exception 1390 * @expectedExceptionMessage Invalid file path 1391 * @covers ::create_file_from_storedfile 1392 */ 1393 public function test_create_file_from_storedfile_filepath_invalid() { 1394 $this->resetAfterTest(true); 1395 1396 $filerecord = $this->generate_file_record(); 1397 1398 $fs = get_file_storage(); 1399 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1400 $this->assertInstanceOf('stored_file', $file1); 1401 1402 $filerecord->filename = 'invalid.txt'; 1403 $filerecord->filepath = 'a-/bad/-filepath'; 1404 1405 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1406 } 1407 1408 /** 1409 * @expectedException file_exception 1410 * @expectedExceptionMessage Invalid file name 1411 * @covers ::create_file_from_storedfile 1412 */ 1413 public function test_create_file_from_storedfile_filename_invalid() { 1414 $this->resetAfterTest(true); 1415 1416 $filerecord = $this->generate_file_record(); 1417 1418 $fs = get_file_storage(); 1419 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1420 $this->assertInstanceOf('stored_file', $file1); 1421 1422 $filerecord->filename = ''; 1423 1424 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1425 } 1426 1427 /** 1428 * @expectedException file_exception 1429 * @expectedExceptionMessage Invalid file timecreated 1430 * @covers ::create_file_from_storedfile 1431 */ 1432 public function test_create_file_from_storedfile_timecreated_invalid() { 1433 $this->resetAfterTest(true); 1434 1435 $filerecord = $this->generate_file_record(); 1436 1437 $fs = get_file_storage(); 1438 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1439 $this->assertInstanceOf('stored_file', $file1); 1440 1441 $filerecord->filename = 'invalid.txt'; 1442 $filerecord->timecreated = 'today'; 1443 1444 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1445 } 1446 1447 /** 1448 * @expectedException file_exception 1449 * @expectedExceptionMessage Invalid file timemodified 1450 * @covers ::create_file_from_storedfile 1451 */ 1452 public function test_create_file_from_storedfile_timemodified_invalid() { 1453 $this->resetAfterTest(true); 1454 1455 $filerecord = $this->generate_file_record(); 1456 1457 $fs = get_file_storage(); 1458 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1459 $this->assertInstanceOf('stored_file', $file1); 1460 1461 $filerecord->filename = 'invalid.txt'; 1462 $filerecord->timemodified = 'today'; 1463 1464 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1465 } 1466 1467 /** 1468 * @expectedException stored_file_creation_exception 1469 * @expectedExceptionMessage Cannot create file 1/core/phpunit/0/testfile.txt 1470 * @covers ::create_file_from_storedfile 1471 */ 1472 public function test_create_file_from_storedfile_duplicate() { 1473 $this->resetAfterTest(true); 1474 1475 $filerecord = $this->generate_file_record(); 1476 1477 $fs = get_file_storage(); 1478 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1479 $this->assertInstanceOf('stored_file', $file1); 1480 1481 // Creating a file validating unique constraint. 1482 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1483 } 1484 1485 /** 1486 * Tests for create_file_from_storedfile. 1487 * 1488 * @covers ::create_file_from_storedfile 1489 */ 1490 public function test_create_file_from_storedfile() { 1491 $this->resetAfterTest(true); 1492 1493 $syscontext = context_system::instance(); 1494 1495 $filerecord = new stdClass(); 1496 $filerecord->contextid = $syscontext->id; 1497 $filerecord->component = 'core'; 1498 $filerecord->filearea = 'phpunit'; 1499 $filerecord->filepath = '/'; 1500 $filerecord->filename = 'testfile.txt'; 1501 $filerecord->itemid = 0; 1502 1503 $fs = get_file_storage(); 1504 1505 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1506 $this->assertInstanceOf('stored_file', $file1); 1507 1508 $filerecord->filename = 'test-create-file-from-storedfile.txt'; 1509 $file2 = $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1510 $this->assertInstanceOf('stored_file', $file2); 1511 1512 // These will be normalised to current time.. 1513 $filerecord->timecreated = -100; 1514 $filerecord->timemodified= -100; 1515 $filerecord->filename = 'test-create-file-from-storedfile-bad-dates.txt'; 1516 1517 $file3 = $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1518 $this->assertInstanceOf('stored_file', $file3); 1519 1520 $this->assertNotEquals($file3->get_timemodified(), $filerecord->timemodified); 1521 $this->assertNotEquals($file3->get_timecreated(), $filerecord->timecreated); 1522 } 1523 1524 /** 1525 * @expectedException file_exception 1526 * @expectedExceptionMessage Invalid contextid 1527 * @covers ::create_file_from_string 1528 */ 1529 public function test_create_file_from_string_contextid_invalid() { 1530 $this->resetAfterTest(true); 1531 1532 $filerecord = $this->generate_file_record(); 1533 $fs = get_file_storage(); 1534 1535 $filerecord->contextid = 'invalid'; 1536 1537 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1538 } 1539 1540 /** 1541 * @expectedException file_exception 1542 * @expectedExceptionMessage Invalid component 1543 * @covers ::create_file_from_string 1544 */ 1545 public function test_create_file_from_string_component_invalid() { 1546 $this->resetAfterTest(true); 1547 1548 $filerecord = $this->generate_file_record(); 1549 $fs = get_file_storage(); 1550 1551 $filerecord->component = 'bad/component'; 1552 1553 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1554 } 1555 1556 /** 1557 * @expectedException file_exception 1558 * @expectedExceptionMessage Invalid filearea 1559 * @covers ::create_file_from_string 1560 */ 1561 public function test_create_file_from_string_filearea_invalid() { 1562 $this->resetAfterTest(true); 1563 1564 $filerecord = $this->generate_file_record(); 1565 $fs = get_file_storage(); 1566 1567 $filerecord->filearea = 'bad-filearea'; 1568 1569 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1570 } 1571 1572 /** 1573 * @expectedException file_exception 1574 * @expectedExceptionMessage Invalid itemid 1575 * @covers ::create_file_from_string 1576 */ 1577 public function test_create_file_from_string_itemid_invalid() { 1578 $this->resetAfterTest(true); 1579 1580 $filerecord = $this->generate_file_record(); 1581 $fs = get_file_storage(); 1582 1583 $filerecord->itemid = 'bad-itemid'; 1584 1585 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1586 } 1587 1588 /** 1589 * @expectedException file_exception 1590 * @expectedExceptionMessage Invalid file path 1591 * @covers ::create_file_from_string 1592 */ 1593 public function test_create_file_from_string_filepath_invalid() { 1594 $this->resetAfterTest(true); 1595 1596 $filerecord = $this->generate_file_record(); 1597 $fs = get_file_storage(); 1598 1599 $filerecord->filepath = 'a-/bad/-filepath'; 1600 1601 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1602 } 1603 1604 /** 1605 * @expectedException file_exception 1606 * @expectedExceptionMessage Invalid file name 1607 * @covers ::create_file_from_string 1608 */ 1609 public function test_create_file_from_string_filename_invalid() { 1610 $this->resetAfterTest(true); 1611 1612 $filerecord = $this->generate_file_record(); 1613 $fs = get_file_storage(); 1614 1615 $filerecord->filename = ''; 1616 1617 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1618 } 1619 1620 /** 1621 * @expectedException file_exception 1622 * @expectedExceptionMessage Invalid file timecreated 1623 * @covers ::create_file_from_string 1624 */ 1625 public function test_create_file_from_string_timecreated_invalid() { 1626 $this->resetAfterTest(true); 1627 1628 $filerecord = $this->generate_file_record(); 1629 $fs = get_file_storage(); 1630 1631 $filerecord->timecreated = 'today'; 1632 1633 $this->expectException('file_exception'); 1634 $this->expectExceptionMessage('Invalid file timecreated'); 1635 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1636 } 1637 1638 /** 1639 * @expectedException file_exception 1640 * @expectedExceptionMessage Invalid file timemodified 1641 * @covers ::create_file_from_string 1642 */ 1643 public function test_create_file_from_string_timemodified_invalid() { 1644 $this->resetAfterTest(true); 1645 1646 $filerecord = $this->generate_file_record(); 1647 $fs = get_file_storage(); 1648 1649 $filerecord->timemodified = 'today'; 1650 1651 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1652 } 1653 1654 /** 1655 * Tests for create_file_from_string with a duplicate string. 1656 * @covers ::create_file_from_string 1657 */ 1658 public function test_create_file_from_string_duplicate() { 1659 $this->resetAfterTest(true); 1660 1661 $filerecord = $this->generate_file_record(); 1662 $fs = get_file_storage(); 1663 1664 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1665 1666 // Creating a file validating unique constraint. 1667 $this->expectException('stored_file_creation_exception'); 1668 $file2 = $fs->create_file_from_string($filerecord, 'text contents'); 1669 } 1670 1671 /** 1672 * @expectedException file_exception 1673 * @expectedExceptionMessage Invalid contextid 1674 * @covers ::create_file_from_pathname 1675 */ 1676 public function test_create_file_from_pathname_contextid_invalid() { 1677 global $CFG; 1678 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1679 1680 $this->resetAfterTest(true); 1681 1682 $filerecord = $this->generate_file_record(); 1683 $fs = get_file_storage(); 1684 1685 $filerecord->contextid = 'invalid'; 1686 1687 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1688 } 1689 1690 /** 1691 * @expectedException file_exception 1692 * @expectedExceptionMessage Invalid component 1693 * @covers ::create_file_from_pathname 1694 */ 1695 public function test_create_file_from_pathname_component_invalid() { 1696 global $CFG; 1697 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1698 1699 $this->resetAfterTest(true); 1700 1701 $filerecord = $this->generate_file_record(); 1702 $fs = get_file_storage(); 1703 1704 $filerecord->component = 'bad/component'; 1705 1706 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1707 } 1708 1709 /** 1710 * @expectedException file_exception 1711 * @expectedExceptionMessage Invalid filearea 1712 * @covers ::create_file_from_pathname 1713 */ 1714 public function test_create_file_from_pathname_filearea_invalid() { 1715 global $CFG; 1716 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1717 1718 $this->resetAfterTest(true); 1719 1720 $filerecord = $this->generate_file_record(); 1721 $fs = get_file_storage(); 1722 1723 $filerecord->filearea = 'bad-filearea'; 1724 1725 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1726 } 1727 1728 /** 1729 * @expectedException file_exception 1730 * @expectedExceptionMessage Invalid itemid 1731 * @covers ::create_file_from_pathname 1732 */ 1733 public function test_create_file_from_pathname_itemid_invalid() { 1734 global $CFG; 1735 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1736 1737 $this->resetAfterTest(true); 1738 1739 $filerecord = $this->generate_file_record(); 1740 $fs = get_file_storage(); 1741 1742 $filerecord->itemid = 'bad-itemid'; 1743 1744 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1745 } 1746 1747 /** 1748 * @expectedException file_exception 1749 * @expectedExceptionMessage Invalid file path 1750 * @covers ::create_file_from_pathname 1751 */ 1752 public function test_create_file_from_pathname_filepath_invalid() { 1753 global $CFG; 1754 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1755 1756 $this->resetAfterTest(true); 1757 1758 $filerecord = $this->generate_file_record(); 1759 $fs = get_file_storage(); 1760 1761 $filerecord->filepath = 'a-/bad/-filepath'; 1762 1763 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1764 } 1765 1766 /** 1767 * @expectedException file_exception 1768 * @expectedExceptionMessage Invalid file name 1769 * @covers ::create_file_from_pathname 1770 */ 1771 public function test_create_file_from_pathname_filename_invalid() { 1772 global $CFG; 1773 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1774 1775 $this->resetAfterTest(true); 1776 1777 $filerecord = $this->generate_file_record(); 1778 $fs = get_file_storage(); 1779 1780 $filerecord->filename = ''; 1781 1782 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1783 } 1784 1785 /** 1786 * @expectedException file_exception 1787 * @expectedExceptionMessage Invalid file timecreated 1788 * @covers ::create_file_from_pathname 1789 */ 1790 public function test_create_file_from_pathname_timecreated_invalid() { 1791 global $CFG; 1792 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1793 1794 $this->resetAfterTest(true); 1795 1796 $filerecord = $this->generate_file_record(); 1797 $fs = get_file_storage(); 1798 1799 $filerecord->timecreated = 'today'; 1800 1801 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1802 } 1803 1804 /** 1805 * @expectedException file_exception 1806 * @expectedExceptionMessage Invalid file timemodified 1807 * @covers ::create_file_from_pathname 1808 */ 1809 public function test_create_file_from_pathname_timemodified_invalid() { 1810 global $CFG; 1811 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1812 1813 $this->resetAfterTest(true); 1814 1815 $filerecord = $this->generate_file_record(); 1816 $fs = get_file_storage(); 1817 1818 $filerecord->timemodified = 'today'; 1819 1820 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1821 } 1822 1823 /** 1824 * @expectedException stored_file_creation_exception 1825 * @expectedExceptionMessage Cannot create file 1/core/phpunit/0/testfile.txt 1826 * @covers ::create_file_from_pathname 1827 */ 1828 public function test_create_file_from_pathname_duplicate_file() { 1829 global $CFG; 1830 $this->resetAfterTest(true); 1831 1832 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1833 1834 $filerecord = $this->generate_file_record(); 1835 $fs = get_file_storage(); 1836 1837 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1838 $this->assertInstanceOf('stored_file', $file1); 1839 1840 // Creating a file validating unique constraint. 1841 $file2 = $fs->create_file_from_pathname($filerecord, $path); 1842 } 1843 1844 /** 1845 * Calling stored_file::delete_reference() on a non-reference file throws coding_exception 1846 * 1847 * @covers \stored_file::delete_reference 1848 */ 1849 public function test_delete_reference_on_nonreference() { 1850 1851 $this->resetAfterTest(true); 1852 $user = $this->setup_three_private_files(); 1853 $fs = get_file_storage(); 1854 $repos = repository::get_instances(array('type'=>'user')); 1855 $repo = reset($repos); 1856 1857 $file = null; 1858 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) { 1859 if (!$areafile->is_directory()) { 1860 $file = $areafile; 1861 break; 1862 } 1863 } 1864 $this->assertInstanceOf('stored_file', $file); 1865 $this->assertFalse($file->is_external_file()); 1866 1867 $this->expectException('coding_exception'); 1868 $file->delete_reference(); 1869 } 1870 1871 /** 1872 * Calling stored_file::delete_reference() on a reference file does not affect other 1873 * symlinks to the same original 1874 * 1875 * @covers \stored_file::delete_reference 1876 */ 1877 public function test_delete_reference_one_symlink_does_not_rule_them_all() { 1878 1879 $this->resetAfterTest(true); 1880 $user = $this->setup_three_private_files(); 1881 $fs = get_file_storage(); 1882 $repos = repository::get_instances(array('type'=>'user')); 1883 $repo = reset($repos); 1884 1885 // Create two aliases linking the same original. 1886 1887 $originalfile = null; 1888 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) { 1889 if (!$areafile->is_directory()) { 1890 $originalfile = $areafile; 1891 break; 1892 } 1893 } 1894 $this->assertInstanceOf('stored_file', $originalfile); 1895 1896 // Calling delete_reference() on a non-reference file. 1897 1898 $originalrecord = array( 1899 'contextid' => $originalfile->get_contextid(), 1900 'component' => $originalfile->get_component(), 1901 'filearea' => $originalfile->get_filearea(), 1902 'itemid' => $originalfile->get_itemid(), 1903 'filepath' => $originalfile->get_filepath(), 1904 'filename' => $originalfile->get_filename(), 1905 ); 1906 1907 $aliasrecord = $this->generate_file_record(); 1908 $aliasrecord->filepath = '/A/'; 1909 $aliasrecord->filename = 'symlink.txt'; 1910 1911 $ref = $fs->pack_reference($originalrecord); 1912 $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1913 1914 $aliasrecord->filepath = '/B/'; 1915 $aliasrecord->filename = 'symlink.txt'; 1916 $ref = $fs->pack_reference($originalrecord); 1917 $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1918 1919 // Refetch A/symlink.txt file. 1920 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 1921 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 1922 $this->assertTrue($symlink1->is_external_file()); 1923 1924 // Unlink the A/symlink.txt file. 1925 $symlink1->delete_reference(); 1926 $this->assertFalse($symlink1->is_external_file()); 1927 1928 // Make sure that B/symlink.txt has not been affected. 1929 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 1930 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 1931 $this->assertTrue($symlink2->is_external_file()); 1932 } 1933 1934 /** 1935 * Make sure that when internal file is updated all references to it are 1936 * updated immediately. When it is deleted, the references are converted 1937 * to true copies. 1938 */ 1939 public function test_update_reference_internal() { 1940 purge_all_caches(); 1941 $this->resetAfterTest(true); 1942 $user = $this->setup_three_private_files(); 1943 $fs = get_file_storage(); 1944 $repos = repository::get_instances(array('type' => 'user')); 1945 $repo = reset($repos); 1946 1947 // Create two aliases linking the same original. 1948 1949 $areafiles = array_values($fs->get_area_files($user->ctxid, 'user', 'private', false, 'filename', false)); 1950 1951 $originalfile = $areafiles[0]; 1952 $this->assertInstanceOf('stored_file', $originalfile); 1953 $contenthash = $originalfile->get_contenthash(); 1954 $filesize = $originalfile->get_filesize(); 1955 1956 $substitutefile = $areafiles[1]; 1957 $this->assertInstanceOf('stored_file', $substitutefile); 1958 $newcontenthash = $substitutefile->get_contenthash(); 1959 $newfilesize = $substitutefile->get_filesize(); 1960 1961 $originalrecord = array( 1962 'contextid' => $originalfile->get_contextid(), 1963 'component' => $originalfile->get_component(), 1964 'filearea' => $originalfile->get_filearea(), 1965 'itemid' => $originalfile->get_itemid(), 1966 'filepath' => $originalfile->get_filepath(), 1967 'filename' => $originalfile->get_filename(), 1968 ); 1969 1970 $aliasrecord = $this->generate_file_record(); 1971 $aliasrecord->filepath = '/A/'; 1972 $aliasrecord->filename = 'symlink.txt'; 1973 1974 $ref = $fs->pack_reference($originalrecord); 1975 $symlink1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1976 // Make sure created alias is a reference and has the same size and contenthash as source. 1977 $this->assertEquals($contenthash, $symlink1->get_contenthash()); 1978 $this->assertEquals($filesize, $symlink1->get_filesize()); 1979 $this->assertEquals($repo->id, $symlink1->get_repository_id()); 1980 $this->assertNotEmpty($symlink1->get_referencefileid()); 1981 $referenceid = $symlink1->get_referencefileid(); 1982 1983 $aliasrecord->filepath = '/B/'; 1984 $aliasrecord->filename = 'symlink.txt'; 1985 $ref = $fs->pack_reference($originalrecord); 1986 $symlink2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1987 // Make sure created alias is a reference and has the same size and contenthash as source. 1988 $this->assertEquals($contenthash, $symlink2->get_contenthash()); 1989 $this->assertEquals($filesize, $symlink2->get_filesize()); 1990 $this->assertEquals($repo->id, $symlink2->get_repository_id()); 1991 // Make sure both aliases have the same reference id. 1992 $this->assertEquals($referenceid, $symlink2->get_referencefileid()); 1993 1994 // Overwrite ofiginal file. 1995 $originalfile->replace_file_with($substitutefile); 1996 $this->assertEquals($newcontenthash, $originalfile->get_contenthash()); 1997 $this->assertEquals($newfilesize, $originalfile->get_filesize()); 1998 1999 // References to the internal files must be synchronised immediately. 2000 // Refetch A/symlink.txt file. 2001 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2002 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 2003 $this->assertTrue($symlink1->is_external_file()); 2004 $this->assertEquals($newcontenthash, $symlink1->get_contenthash()); 2005 $this->assertEquals($newfilesize, $symlink1->get_filesize()); 2006 $this->assertEquals($repo->id, $symlink1->get_repository_id()); 2007 $this->assertEquals($referenceid, $symlink1->get_referencefileid()); 2008 2009 // Refetch B/symlink.txt file. 2010 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2011 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 2012 $this->assertTrue($symlink2->is_external_file()); 2013 $this->assertEquals($newcontenthash, $symlink2->get_contenthash()); 2014 $this->assertEquals($newfilesize, $symlink2->get_filesize()); 2015 $this->assertEquals($repo->id, $symlink2->get_repository_id()); 2016 $this->assertEquals($referenceid, $symlink2->get_referencefileid()); 2017 2018 // Remove original file. 2019 $originalfile->delete(); 2020 2021 // References must be converted to independend files. 2022 // Refetch A/symlink.txt file. 2023 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2024 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 2025 $this->assertFalse($symlink1->is_external_file()); 2026 $this->assertEquals($newcontenthash, $symlink1->get_contenthash()); 2027 $this->assertEquals($newfilesize, $symlink1->get_filesize()); 2028 $this->assertNull($symlink1->get_repository_id()); 2029 $this->assertNull($symlink1->get_referencefileid()); 2030 2031 // Refetch B/symlink.txt file. 2032 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2033 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 2034 $this->assertFalse($symlink2->is_external_file()); 2035 $this->assertEquals($newcontenthash, $symlink2->get_contenthash()); 2036 $this->assertEquals($newfilesize, $symlink2->get_filesize()); 2037 $this->assertNull($symlink2->get_repository_id()); 2038 $this->assertNull($symlink2->get_referencefileid()); 2039 } 2040 2041 /** 2042 * Tests for get_unused_filename. 2043 * 2044 * @covers ::get_unused_filename 2045 */ 2046 public function test_get_unused_filename() { 2047 global $USER; 2048 $this->resetAfterTest(true); 2049 2050 $fs = get_file_storage(); 2051 $this->setAdminUser(); 2052 $contextid = context_user::instance($USER->id)->id; 2053 $component = 'user'; 2054 $filearea = 'private'; 2055 $itemid = 0; 2056 $filepath = '/'; 2057 2058 // Create some private files. 2059 $file = new stdClass; 2060 $file->contextid = $contextid; 2061 $file->component = 'user'; 2062 $file->filearea = 'private'; 2063 $file->itemid = 0; 2064 $file->filepath = '/'; 2065 $file->source = 'test'; 2066 $filenames = array('foo.txt', 'foo (1).txt', 'foo (20).txt', 'foo (999)', 'bar.jpg', 'What (a cool file).jpg', 2067 'Hurray! (1).php', 'Hurray! (2).php', 'Hurray! (9a).php', 'Hurray! (abc).php'); 2068 foreach ($filenames as $key => $filename) { 2069 $file->filename = $filename; 2070 $userfile = $fs->create_file_from_string($file, "file $key $filename content"); 2071 $this->assertInstanceOf('stored_file', $userfile); 2072 } 2073 2074 // Asserting new generated names. 2075 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'unused.txt'); 2076 $this->assertEquals('unused.txt', $newfilename); 2077 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo.txt'); 2078 $this->assertEquals('foo (21).txt', $newfilename); 2079 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (1).txt'); 2080 $this->assertEquals('foo (21).txt', $newfilename); 2081 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (2).txt'); 2082 $this->assertEquals('foo (2).txt', $newfilename); 2083 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (20).txt'); 2084 $this->assertEquals('foo (21).txt', $newfilename); 2085 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo'); 2086 $this->assertEquals('foo', $newfilename); 2087 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (123)'); 2088 $this->assertEquals('foo (123)', $newfilename); 2089 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (999)'); 2090 $this->assertEquals('foo (1000)', $newfilename); 2091 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.png'); 2092 $this->assertEquals('bar.png', $newfilename); 2093 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (12).png'); 2094 $this->assertEquals('bar (12).png', $newfilename); 2095 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.jpg'); 2096 $this->assertEquals('bar (1).jpg', $newfilename); 2097 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (1).jpg'); 2098 $this->assertEquals('bar (1).jpg', $newfilename); 2099 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'What (a cool file).jpg'); 2100 $this->assertEquals('What (a cool file) (1).jpg', $newfilename); 2101 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'Hurray! (1).php'); 2102 $this->assertEquals('Hurray! (3).php', $newfilename); 2103 2104 $this->expectException('coding_exception'); 2105 $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, ''); 2106 } 2107 2108 /** 2109 * Test that mimetype_from_file returns appropriate output when the 2110 * file could not be found. 2111 * 2112 * @covers ::mimetype 2113 */ 2114 public function test_mimetype_not_found() { 2115 $mimetype = file_storage::mimetype('/path/to/nonexistent/file'); 2116 $this->assertEquals('document/unknown', $mimetype); 2117 } 2118 2119 /** 2120 * Test that mimetype_from_file returns appropriate output for a known 2121 * file. 2122 * 2123 * Note: this is not intended to check that functions outside of this 2124 * file works. It is intended to validate the codepath contains no 2125 * errors and behaves as expected. 2126 * 2127 * @covers ::mimetype 2128 */ 2129 public function test_mimetype_known() { 2130 $filepath = __DIR__ . '/fixtures/testimage.jpg'; 2131 $mimetype = file_storage::mimetype_from_file($filepath); 2132 $this->assertEquals('image/jpeg', $mimetype); 2133 } 2134 2135 /** 2136 * Test that mimetype_from_file returns appropriate output when the 2137 * file could not be found. 2138 * 2139 * @covers ::mimetype 2140 */ 2141 public function test_mimetype_from_file_not_found() { 2142 $mimetype = file_storage::mimetype_from_file('/path/to/nonexistent/file'); 2143 $this->assertEquals('document/unknown', $mimetype); 2144 } 2145 2146 /** 2147 * Test that mimetype_from_file returns appropriate output for a known 2148 * file. 2149 * 2150 * Note: this is not intended to check that functions outside of this 2151 * file works. It is intended to validate the codepath contains no 2152 * errors and behaves as expected. 2153 * 2154 * @covers ::mimetype 2155 */ 2156 public function test_mimetype_from_file_known() { 2157 $filepath = __DIR__ . '/fixtures/testimage.jpg'; 2158 $mimetype = file_storage::mimetype_from_file($filepath); 2159 $this->assertEquals('image/jpeg', $mimetype); 2160 } 2161 2162 } 2163 2164 class test_stored_file_inspection extends stored_file { 2165 public static function get_pretected_pathname(stored_file $file) { 2166 return $file->get_pathname_by_contenthash(); 2167 } 2168 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body