Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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 * @covers ::create_file_from_storedfile 1295 */ 1296 public function test_create_file_from_storedfile_file_invalid() { 1297 $this->resetAfterTest(true); 1298 1299 $filerecord = $this->generate_file_record(); 1300 1301 $fs = get_file_storage(); 1302 1303 // Create a file from a file id which doesn't exist. 1304 $this->expectException(file_exception::class); 1305 $fs->create_file_from_storedfile($filerecord, 9999); 1306 } 1307 1308 /** 1309 * @covers ::create_file_from_storedfile 1310 */ 1311 public function test_create_file_from_storedfile_contextid_invalid() { 1312 $this->resetAfterTest(true); 1313 1314 $filerecord = $this->generate_file_record(); 1315 1316 $fs = get_file_storage(); 1317 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1318 $this->assertInstanceOf('stored_file', $file1); 1319 1320 $filerecord->filename = 'invalid.txt'; 1321 $filerecord->contextid = 'invalid'; 1322 1323 $this->expectException(file_exception::class); 1324 $this->expectExceptionMessage('Invalid contextid'); 1325 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1326 } 1327 1328 /** 1329 * @covers ::create_file_from_storedfile 1330 */ 1331 public function test_create_file_from_storedfile_component_invalid() { 1332 $this->resetAfterTest(true); 1333 1334 $filerecord = $this->generate_file_record(); 1335 1336 $fs = get_file_storage(); 1337 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1338 $this->assertInstanceOf('stored_file', $file1); 1339 1340 $filerecord->filename = 'invalid.txt'; 1341 $filerecord->component = 'bad/component'; 1342 1343 $this->expectException(file_exception::class); 1344 $this->expectExceptionMessage('Invalid component'); 1345 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1346 } 1347 1348 /** 1349 * @covers ::create_file_from_storedfile 1350 */ 1351 public function test_create_file_from_storedfile_filearea_invalid() { 1352 $this->resetAfterTest(true); 1353 1354 $filerecord = $this->generate_file_record(); 1355 1356 $fs = get_file_storage(); 1357 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1358 $this->assertInstanceOf('stored_file', $file1); 1359 1360 $filerecord->filename = 'invalid.txt'; 1361 $filerecord->filearea = 'bad-filearea'; 1362 1363 $this->expectException(file_exception::class); 1364 $this->expectExceptionMessage('Invalid filearea'); 1365 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1366 } 1367 1368 /** 1369 * @covers ::create_file_from_storedfile 1370 */ 1371 public function test_create_file_from_storedfile_itemid_invalid() { 1372 $this->resetAfterTest(true); 1373 1374 $filerecord = $this->generate_file_record(); 1375 1376 $fs = get_file_storage(); 1377 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1378 $this->assertInstanceOf('stored_file', $file1); 1379 1380 $filerecord->filename = 'invalid.txt'; 1381 $filerecord->itemid = 'bad-itemid'; 1382 1383 $this->expectException(file_exception::class); 1384 $this->expectExceptionMessage('Invalid itemid'); 1385 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1386 } 1387 1388 /** 1389 * @covers ::create_file_from_storedfile 1390 */ 1391 public function test_create_file_from_storedfile_filepath_invalid() { 1392 $this->resetAfterTest(true); 1393 1394 $filerecord = $this->generate_file_record(); 1395 1396 $fs = get_file_storage(); 1397 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1398 $this->assertInstanceOf('stored_file', $file1); 1399 1400 $filerecord->filename = 'invalid.txt'; 1401 $filerecord->filepath = 'a-/bad/-filepath'; 1402 1403 $this->expectException(file_exception::class); 1404 $this->expectExceptionMessage('Invalid file path'); 1405 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1406 } 1407 1408 /** 1409 * @covers ::create_file_from_storedfile 1410 */ 1411 public function test_create_file_from_storedfile_filename_invalid() { 1412 $this->resetAfterTest(true); 1413 1414 $filerecord = $this->generate_file_record(); 1415 1416 $fs = get_file_storage(); 1417 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1418 $this->assertInstanceOf('stored_file', $file1); 1419 1420 $filerecord->filename = ''; 1421 1422 $this->expectException(file_exception::class); 1423 $this->expectExceptionMessage('Invalid file name'); 1424 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1425 } 1426 1427 /** 1428 * @covers ::create_file_from_storedfile 1429 */ 1430 public function test_create_file_from_storedfile_timecreated_invalid() { 1431 $this->resetAfterTest(true); 1432 1433 $filerecord = $this->generate_file_record(); 1434 1435 $fs = get_file_storage(); 1436 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1437 $this->assertInstanceOf('stored_file', $file1); 1438 1439 $filerecord->filename = 'invalid.txt'; 1440 $filerecord->timecreated = 'today'; 1441 1442 $this->expectException(file_exception::class); 1443 $this->expectExceptionMessage('Invalid file timecreated'); 1444 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1445 } 1446 1447 /** 1448 * @covers ::create_file_from_storedfile 1449 */ 1450 public function test_create_file_from_storedfile_timemodified_invalid() { 1451 $this->resetAfterTest(true); 1452 1453 $filerecord = $this->generate_file_record(); 1454 1455 $fs = get_file_storage(); 1456 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1457 $this->assertInstanceOf('stored_file', $file1); 1458 1459 $filerecord->filename = 'invalid.txt'; 1460 $filerecord->timemodified = 'today'; 1461 1462 $this->expectException(file_exception::class); 1463 $this->expectExceptionMessage('Invalid file timemodified'); 1464 $fs->create_file_from_storedfile($filerecord, $file1->get_id()); 1465 } 1466 1467 /** 1468 * @covers ::create_file_from_storedfile 1469 */ 1470 public function test_create_file_from_storedfile_duplicate() { 1471 $this->resetAfterTest(true); 1472 1473 $filerecord = $this->generate_file_record(); 1474 1475 $fs = get_file_storage(); 1476 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1477 $this->assertInstanceOf('stored_file', $file1); 1478 1479 // Creating a file validating unique constraint. 1480 $this->expectException(stored_file_creation_exception::class); 1481 $this->expectExceptionMessage('Cannot create file 1/core/phpunit/0/testfile.txt'); 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 * @covers ::create_file_from_string 1526 */ 1527 public function test_create_file_from_string_contextid_invalid() { 1528 $this->resetAfterTest(true); 1529 1530 $filerecord = $this->generate_file_record(); 1531 $fs = get_file_storage(); 1532 1533 $filerecord->contextid = 'invalid'; 1534 1535 $this->expectException(file_exception::class); 1536 $this->expectExceptionMessage('Invalid contextid'); 1537 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1538 } 1539 1540 /** 1541 * @covers ::create_file_from_string 1542 */ 1543 public function test_create_file_from_string_component_invalid() { 1544 $this->resetAfterTest(true); 1545 1546 $filerecord = $this->generate_file_record(); 1547 $fs = get_file_storage(); 1548 1549 $filerecord->component = 'bad/component'; 1550 1551 $this->expectException(file_exception::class); 1552 $this->expectExceptionMessage('Invalid component'); 1553 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1554 } 1555 1556 /** 1557 * @covers ::create_file_from_string 1558 */ 1559 public function test_create_file_from_string_filearea_invalid() { 1560 $this->resetAfterTest(true); 1561 1562 $filerecord = $this->generate_file_record(); 1563 $fs = get_file_storage(); 1564 1565 $filerecord->filearea = 'bad-filearea'; 1566 1567 $this->expectException(file_exception::class); 1568 $this->expectExceptionMessage('Invalid filearea'); 1569 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1570 } 1571 1572 /** 1573 * @covers ::create_file_from_string 1574 */ 1575 public function test_create_file_from_string_itemid_invalid() { 1576 $this->resetAfterTest(true); 1577 1578 $filerecord = $this->generate_file_record(); 1579 $fs = get_file_storage(); 1580 1581 $filerecord->itemid = 'bad-itemid'; 1582 1583 $this->expectException(file_exception::class); 1584 $this->expectExceptionMessage('Invalid itemid'); 1585 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1586 } 1587 1588 /** 1589 * @covers ::create_file_from_string 1590 */ 1591 public function test_create_file_from_string_filepath_invalid() { 1592 $this->resetAfterTest(true); 1593 1594 $filerecord = $this->generate_file_record(); 1595 $fs = get_file_storage(); 1596 1597 $filerecord->filepath = 'a-/bad/-filepath'; 1598 1599 $this->expectException(file_exception::class); 1600 $this->expectExceptionMessage('Invalid file path'); 1601 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1602 } 1603 1604 /** 1605 * @covers ::create_file_from_string 1606 */ 1607 public function test_create_file_from_string_filename_invalid() { 1608 $this->resetAfterTest(true); 1609 1610 $filerecord = $this->generate_file_record(); 1611 $fs = get_file_storage(); 1612 1613 $filerecord->filename = ''; 1614 1615 $this->expectException(file_exception::class); 1616 $this->expectExceptionMessage('Invalid file name'); 1617 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1618 } 1619 1620 /** 1621 * @covers ::create_file_from_string 1622 */ 1623 public function test_create_file_from_string_timecreated_invalid() { 1624 $this->resetAfterTest(true); 1625 1626 $filerecord = $this->generate_file_record(); 1627 $fs = get_file_storage(); 1628 1629 $filerecord->timecreated = 'today'; 1630 1631 $this->expectException('file_exception'); 1632 $this->expectExceptionMessage('Invalid file timecreated'); 1633 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1634 } 1635 1636 /** 1637 * @covers ::create_file_from_string 1638 */ 1639 public function test_create_file_from_string_timemodified_invalid() { 1640 $this->resetAfterTest(true); 1641 1642 $filerecord = $this->generate_file_record(); 1643 $fs = get_file_storage(); 1644 1645 $filerecord->timemodified = 'today'; 1646 1647 $this->expectException(file_exception::class); 1648 $this->expectExceptionMessage('Invalid file timemodified'); 1649 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1650 } 1651 1652 /** 1653 * Tests for create_file_from_string with a duplicate string. 1654 * @covers ::create_file_from_string 1655 */ 1656 public function test_create_file_from_string_duplicate() { 1657 $this->resetAfterTest(true); 1658 1659 $filerecord = $this->generate_file_record(); 1660 $fs = get_file_storage(); 1661 1662 $file1 = $fs->create_file_from_string($filerecord, 'text contents'); 1663 1664 // Creating a file validating unique constraint. 1665 $this->expectException('stored_file_creation_exception'); 1666 $file2 = $fs->create_file_from_string($filerecord, 'text contents'); 1667 } 1668 1669 /** 1670 * @covers ::create_file_from_pathname 1671 */ 1672 public function test_create_file_from_pathname_contextid_invalid() { 1673 global $CFG; 1674 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1675 1676 $this->resetAfterTest(true); 1677 1678 $filerecord = $this->generate_file_record(); 1679 $fs = get_file_storage(); 1680 1681 $filerecord->contextid = 'invalid'; 1682 1683 $this->expectException(file_exception::class); 1684 $this->expectExceptionMessage('Invalid contextid'); 1685 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1686 } 1687 1688 /** 1689 * @covers ::create_file_from_pathname 1690 */ 1691 public function test_create_file_from_pathname_component_invalid() { 1692 global $CFG; 1693 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1694 1695 $this->resetAfterTest(true); 1696 1697 $filerecord = $this->generate_file_record(); 1698 $fs = get_file_storage(); 1699 1700 $filerecord->component = 'bad/component'; 1701 1702 $this->expectException(file_exception::class); 1703 $this->expectExceptionMessage('Invalid component'); 1704 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1705 } 1706 1707 /** 1708 * @covers ::create_file_from_pathname 1709 */ 1710 public function test_create_file_from_pathname_filearea_invalid() { 1711 global $CFG; 1712 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1713 1714 $this->resetAfterTest(true); 1715 1716 $filerecord = $this->generate_file_record(); 1717 $fs = get_file_storage(); 1718 1719 $filerecord->filearea = 'bad-filearea'; 1720 1721 $this->expectException(file_exception::class); 1722 $this->expectExceptionMessage('Invalid filearea'); 1723 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1724 } 1725 1726 /** 1727 * @covers ::create_file_from_pathname 1728 */ 1729 public function test_create_file_from_pathname_itemid_invalid() { 1730 global $CFG; 1731 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1732 1733 $this->resetAfterTest(true); 1734 1735 $filerecord = $this->generate_file_record(); 1736 $fs = get_file_storage(); 1737 1738 $filerecord->itemid = 'bad-itemid'; 1739 1740 $this->expectException(file_exception::class); 1741 $this->expectExceptionMessage('Invalid itemid'); 1742 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1743 } 1744 1745 /** 1746 * @covers ::create_file_from_pathname 1747 */ 1748 public function test_create_file_from_pathname_filepath_invalid() { 1749 global $CFG; 1750 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1751 1752 $this->resetAfterTest(true); 1753 1754 $filerecord = $this->generate_file_record(); 1755 $fs = get_file_storage(); 1756 1757 $filerecord->filepath = 'a-/bad/-filepath'; 1758 1759 $this->expectException(file_exception::class); 1760 $this->expectExceptionMessage('Invalid file path'); 1761 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1762 } 1763 1764 /** 1765 * @covers ::create_file_from_pathname 1766 */ 1767 public function test_create_file_from_pathname_filename_invalid() { 1768 global $CFG; 1769 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1770 1771 $this->resetAfterTest(true); 1772 1773 $filerecord = $this->generate_file_record(); 1774 $fs = get_file_storage(); 1775 1776 $filerecord->filename = ''; 1777 1778 $this->expectException(file_exception::class); 1779 $this->expectExceptionMessage('Invalid file name'); 1780 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1781 } 1782 1783 /** 1784 * @covers ::create_file_from_pathname 1785 */ 1786 public function test_create_file_from_pathname_timecreated_invalid() { 1787 global $CFG; 1788 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1789 1790 $this->resetAfterTest(true); 1791 1792 $filerecord = $this->generate_file_record(); 1793 $fs = get_file_storage(); 1794 1795 $filerecord->timecreated = 'today'; 1796 1797 $this->expectException(file_exception::class); 1798 $this->expectExceptionMessage('Invalid file timecreated'); 1799 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1800 } 1801 1802 /** 1803 * @covers ::create_file_from_pathname 1804 */ 1805 public function test_create_file_from_pathname_timemodified_invalid() { 1806 global $CFG; 1807 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1808 1809 $this->resetAfterTest(true); 1810 1811 $filerecord = $this->generate_file_record(); 1812 $fs = get_file_storage(); 1813 1814 $filerecord->timemodified = 'today'; 1815 1816 $this->expectException(file_exception::class); 1817 $this->expectExceptionMessage('Invalid file timemodified'); 1818 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1819 } 1820 1821 /** 1822 * @covers ::create_file_from_pathname 1823 */ 1824 public function test_create_file_from_pathname_duplicate_file() { 1825 global $CFG; 1826 $this->resetAfterTest(true); 1827 1828 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg'; 1829 1830 $filerecord = $this->generate_file_record(); 1831 $fs = get_file_storage(); 1832 1833 $file1 = $fs->create_file_from_pathname($filerecord, $path); 1834 $this->assertInstanceOf('stored_file', $file1); 1835 1836 // Creating a file validating unique constraint. 1837 $this->expectException(stored_file_creation_exception::class); 1838 $this->expectExceptionMessage('Cannot create file 1/core/phpunit/0/testfile.txt'); 1839 $file2 = $fs->create_file_from_pathname($filerecord, $path); 1840 } 1841 1842 /** 1843 * Calling stored_file::delete_reference() on a non-reference file throws coding_exception 1844 * 1845 * @covers \stored_file::delete_reference 1846 */ 1847 public function test_delete_reference_on_nonreference() { 1848 1849 $this->resetAfterTest(true); 1850 $user = $this->setup_three_private_files(); 1851 $fs = get_file_storage(); 1852 $repos = repository::get_instances(array('type'=>'user')); 1853 $repo = reset($repos); 1854 1855 $file = null; 1856 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) { 1857 if (!$areafile->is_directory()) { 1858 $file = $areafile; 1859 break; 1860 } 1861 } 1862 $this->assertInstanceOf('stored_file', $file); 1863 $this->assertFalse($file->is_external_file()); 1864 1865 $this->expectException('coding_exception'); 1866 $file->delete_reference(); 1867 } 1868 1869 /** 1870 * Calling stored_file::delete_reference() on a reference file does not affect other 1871 * symlinks to the same original 1872 * 1873 * @covers \stored_file::delete_reference 1874 */ 1875 public function test_delete_reference_one_symlink_does_not_rule_them_all() { 1876 1877 $this->resetAfterTest(true); 1878 $user = $this->setup_three_private_files(); 1879 $fs = get_file_storage(); 1880 $repos = repository::get_instances(array('type'=>'user')); 1881 $repo = reset($repos); 1882 1883 // Create two aliases linking the same original. 1884 1885 $originalfile = null; 1886 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) { 1887 if (!$areafile->is_directory()) { 1888 $originalfile = $areafile; 1889 break; 1890 } 1891 } 1892 $this->assertInstanceOf('stored_file', $originalfile); 1893 1894 // Calling delete_reference() on a non-reference file. 1895 1896 $originalrecord = array( 1897 'contextid' => $originalfile->get_contextid(), 1898 'component' => $originalfile->get_component(), 1899 'filearea' => $originalfile->get_filearea(), 1900 'itemid' => $originalfile->get_itemid(), 1901 'filepath' => $originalfile->get_filepath(), 1902 'filename' => $originalfile->get_filename(), 1903 ); 1904 1905 $aliasrecord = $this->generate_file_record(); 1906 $aliasrecord->filepath = '/A/'; 1907 $aliasrecord->filename = 'symlink.txt'; 1908 1909 $ref = $fs->pack_reference($originalrecord); 1910 $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1911 1912 $aliasrecord->filepath = '/B/'; 1913 $aliasrecord->filename = 'symlink.txt'; 1914 $ref = $fs->pack_reference($originalrecord); 1915 $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1916 1917 // Refetch A/symlink.txt file. 1918 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 1919 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 1920 $this->assertTrue($symlink1->is_external_file()); 1921 1922 // Unlink the A/symlink.txt file. 1923 $symlink1->delete_reference(); 1924 $this->assertFalse($symlink1->is_external_file()); 1925 1926 // Make sure that B/symlink.txt has not been affected. 1927 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 1928 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 1929 $this->assertTrue($symlink2->is_external_file()); 1930 } 1931 1932 /** 1933 * Make sure that when internal file is updated all references to it are 1934 * updated immediately. When it is deleted, the references are converted 1935 * to true copies. 1936 */ 1937 public function test_update_reference_internal() { 1938 purge_all_caches(); 1939 $this->resetAfterTest(true); 1940 $user = $this->setup_three_private_files(); 1941 $fs = get_file_storage(); 1942 $repos = repository::get_instances(array('type' => 'user')); 1943 $repo = reset($repos); 1944 1945 // Create two aliases linking the same original. 1946 1947 $areafiles = array_values($fs->get_area_files($user->ctxid, 'user', 'private', false, 'filename', false)); 1948 1949 $originalfile = $areafiles[0]; 1950 $this->assertInstanceOf('stored_file', $originalfile); 1951 $contenthash = $originalfile->get_contenthash(); 1952 $filesize = $originalfile->get_filesize(); 1953 1954 $substitutefile = $areafiles[1]; 1955 $this->assertInstanceOf('stored_file', $substitutefile); 1956 $newcontenthash = $substitutefile->get_contenthash(); 1957 $newfilesize = $substitutefile->get_filesize(); 1958 1959 $originalrecord = array( 1960 'contextid' => $originalfile->get_contextid(), 1961 'component' => $originalfile->get_component(), 1962 'filearea' => $originalfile->get_filearea(), 1963 'itemid' => $originalfile->get_itemid(), 1964 'filepath' => $originalfile->get_filepath(), 1965 'filename' => $originalfile->get_filename(), 1966 ); 1967 1968 $aliasrecord = $this->generate_file_record(); 1969 $aliasrecord->filepath = '/A/'; 1970 $aliasrecord->filename = 'symlink.txt'; 1971 1972 $ref = $fs->pack_reference($originalrecord); 1973 $symlink1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1974 // Make sure created alias is a reference and has the same size and contenthash as source. 1975 $this->assertEquals($contenthash, $symlink1->get_contenthash()); 1976 $this->assertEquals($filesize, $symlink1->get_filesize()); 1977 $this->assertEquals($repo->id, $symlink1->get_repository_id()); 1978 $this->assertNotEmpty($symlink1->get_referencefileid()); 1979 $referenceid = $symlink1->get_referencefileid(); 1980 1981 $aliasrecord->filepath = '/B/'; 1982 $aliasrecord->filename = 'symlink.txt'; 1983 $ref = $fs->pack_reference($originalrecord); 1984 $symlink2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref); 1985 // Make sure created alias is a reference and has the same size and contenthash as source. 1986 $this->assertEquals($contenthash, $symlink2->get_contenthash()); 1987 $this->assertEquals($filesize, $symlink2->get_filesize()); 1988 $this->assertEquals($repo->id, $symlink2->get_repository_id()); 1989 // Make sure both aliases have the same reference id. 1990 $this->assertEquals($referenceid, $symlink2->get_referencefileid()); 1991 1992 // Overwrite ofiginal file. 1993 $originalfile->replace_file_with($substitutefile); 1994 $this->assertEquals($newcontenthash, $originalfile->get_contenthash()); 1995 $this->assertEquals($newfilesize, $originalfile->get_filesize()); 1996 1997 // References to the internal files must be synchronised immediately. 1998 // Refetch A/symlink.txt file. 1999 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2000 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 2001 $this->assertTrue($symlink1->is_external_file()); 2002 $this->assertEquals($newcontenthash, $symlink1->get_contenthash()); 2003 $this->assertEquals($newfilesize, $symlink1->get_filesize()); 2004 $this->assertEquals($repo->id, $symlink1->get_repository_id()); 2005 $this->assertEquals($referenceid, $symlink1->get_referencefileid()); 2006 2007 // Refetch B/symlink.txt file. 2008 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2009 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 2010 $this->assertTrue($symlink2->is_external_file()); 2011 $this->assertEquals($newcontenthash, $symlink2->get_contenthash()); 2012 $this->assertEquals($newfilesize, $symlink2->get_filesize()); 2013 $this->assertEquals($repo->id, $symlink2->get_repository_id()); 2014 $this->assertEquals($referenceid, $symlink2->get_referencefileid()); 2015 2016 // Remove original file. 2017 $originalfile->delete(); 2018 2019 // References must be converted to independend files. 2020 // Refetch A/symlink.txt file. 2021 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2022 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt'); 2023 $this->assertFalse($symlink1->is_external_file()); 2024 $this->assertEquals($newcontenthash, $symlink1->get_contenthash()); 2025 $this->assertEquals($newfilesize, $symlink1->get_filesize()); 2026 $this->assertNull($symlink1->get_repository_id()); 2027 $this->assertNull($symlink1->get_referencefileid()); 2028 2029 // Refetch B/symlink.txt file. 2030 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component, 2031 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt'); 2032 $this->assertFalse($symlink2->is_external_file()); 2033 $this->assertEquals($newcontenthash, $symlink2->get_contenthash()); 2034 $this->assertEquals($newfilesize, $symlink2->get_filesize()); 2035 $this->assertNull($symlink2->get_repository_id()); 2036 $this->assertNull($symlink2->get_referencefileid()); 2037 } 2038 2039 /** 2040 * Tests for get_unused_filename. 2041 * 2042 * @covers ::get_unused_filename 2043 */ 2044 public function test_get_unused_filename() { 2045 global $USER; 2046 $this->resetAfterTest(true); 2047 2048 $fs = get_file_storage(); 2049 $this->setAdminUser(); 2050 $contextid = context_user::instance($USER->id)->id; 2051 $component = 'user'; 2052 $filearea = 'private'; 2053 $itemid = 0; 2054 $filepath = '/'; 2055 2056 // Create some private files. 2057 $file = new stdClass; 2058 $file->contextid = $contextid; 2059 $file->component = 'user'; 2060 $file->filearea = 'private'; 2061 $file->itemid = 0; 2062 $file->filepath = '/'; 2063 $file->source = 'test'; 2064 $filenames = array('foo.txt', 'foo (1).txt', 'foo (20).txt', 'foo (999)', 'bar.jpg', 'What (a cool file).jpg', 2065 'Hurray! (1).php', 'Hurray! (2).php', 'Hurray! (9a).php', 'Hurray! (abc).php'); 2066 foreach ($filenames as $key => $filename) { 2067 $file->filename = $filename; 2068 $userfile = $fs->create_file_from_string($file, "file $key $filename content"); 2069 $this->assertInstanceOf('stored_file', $userfile); 2070 } 2071 2072 // Asserting new generated names. 2073 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'unused.txt'); 2074 $this->assertEquals('unused.txt', $newfilename); 2075 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo.txt'); 2076 $this->assertEquals('foo (21).txt', $newfilename); 2077 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (1).txt'); 2078 $this->assertEquals('foo (21).txt', $newfilename); 2079 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (2).txt'); 2080 $this->assertEquals('foo (2).txt', $newfilename); 2081 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (20).txt'); 2082 $this->assertEquals('foo (21).txt', $newfilename); 2083 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo'); 2084 $this->assertEquals('foo', $newfilename); 2085 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (123)'); 2086 $this->assertEquals('foo (123)', $newfilename); 2087 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (999)'); 2088 $this->assertEquals('foo (1000)', $newfilename); 2089 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.png'); 2090 $this->assertEquals('bar.png', $newfilename); 2091 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (12).png'); 2092 $this->assertEquals('bar (12).png', $newfilename); 2093 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.jpg'); 2094 $this->assertEquals('bar (1).jpg', $newfilename); 2095 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (1).jpg'); 2096 $this->assertEquals('bar (1).jpg', $newfilename); 2097 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'What (a cool file).jpg'); 2098 $this->assertEquals('What (a cool file) (1).jpg', $newfilename); 2099 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'Hurray! (1).php'); 2100 $this->assertEquals('Hurray! (3).php', $newfilename); 2101 2102 $this->expectException('coding_exception'); 2103 $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, ''); 2104 } 2105 2106 /** 2107 * Test that mimetype_from_file returns appropriate output when the 2108 * file could not be found. 2109 * 2110 * @covers ::mimetype 2111 */ 2112 public function test_mimetype_not_found() { 2113 $mimetype = file_storage::mimetype('/path/to/nonexistent/file'); 2114 $this->assertEquals('document/unknown', $mimetype); 2115 } 2116 2117 /** 2118 * Test that mimetype_from_file returns appropriate output for a known 2119 * file. 2120 * 2121 * Note: this is not intended to check that functions outside of this 2122 * file works. It is intended to validate the codepath contains no 2123 * errors and behaves as expected. 2124 * 2125 * @covers ::mimetype 2126 */ 2127 public function test_mimetype_known() { 2128 $filepath = __DIR__ . '/fixtures/testimage.jpg'; 2129 $mimetype = file_storage::mimetype_from_file($filepath); 2130 $this->assertEquals('image/jpeg', $mimetype); 2131 } 2132 2133 /** 2134 * Test that mimetype_from_file returns appropriate output when the 2135 * file could not be found. 2136 * 2137 * @covers ::mimetype 2138 */ 2139 public function test_mimetype_from_file_not_found() { 2140 $mimetype = file_storage::mimetype_from_file('/path/to/nonexistent/file'); 2141 $this->assertEquals('document/unknown', $mimetype); 2142 } 2143 2144 /** 2145 * Test that mimetype_from_file returns appropriate output for a known 2146 * file. 2147 * 2148 * Note: this is not intended to check that functions outside of this 2149 * file works. It is intended to validate the codepath contains no 2150 * errors and behaves as expected. 2151 * 2152 * @covers ::mimetype 2153 */ 2154 public function test_mimetype_from_file_known() { 2155 $filepath = __DIR__ . '/fixtures/testimage.jpg'; 2156 $mimetype = file_storage::mimetype_from_file($filepath); 2157 $this->assertEquals('image/jpeg', $mimetype); 2158 } 2159 2160 } 2161 2162 class test_stored_file_inspection extends stored_file { 2163 public static function get_pretected_pathname(stored_file $file) { 2164 return $file->get_pathname_by_contenthash(); 2165 } 2166 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body