2008-08-25 03:42:27 +02:00
< ? php
/**
* Tests for the File class
*/
class FileTest extends SapphireTest {
2010-06-29 06:59:45 +02:00
2008-08-25 03:42:27 +02:00
static $fixture_file = 'sapphire/tests/filesystem/FileTest.yml' ;
2010-06-29 06:59:48 +02:00
function testCreateWithFilenameWithSubfolder () {
// Note: We can't use fixtures/setUp() for this, as we want to create the db record manually.
// Creating the folder is necessary to avoid having "Filename" overwritten by setName()/setRelativePath(),
// because the parent folders don't exist in the database
$folder = Folder :: findOrMake ( '/FileTest/' );
$testfilePath = 'assets/FileTest/CreateWithFilenameHasCorrectPath.txt' ; // Important: No leading slash
$fh = fopen ( BASE_PATH . '/' . $testfilePath , " w " );
fwrite ( $fh , str_repeat ( 'x' , 1000000 ));
fclose ( $fh );
$file = new File ();
$file -> Filename = $testfilePath ;
// TODO This should be auto-detected
$file -> ParentID = $folder -> ID ;
$file -> write ();
$this -> assertEquals ( 'CreateWithFilenameHasCorrectPath.txt' , $file -> Name , '"Name" property is automatically set from "Filename"' );
$this -> assertEquals ( $testfilePath , $file -> Filename , '"Filename" property remains unchanged' );
// TODO This should be auto-detected, see File->updateFilesystem()
// $this->assertType('Folder', $file->Parent(), 'Parent folder is created in database');
// $this->assertFileExists($file->Parent()->getFullPath(), 'Parent folder is created on filesystem');
// $this->assertEquals('FileTest', $file->Parent()->Name);
// $this->assertType('Folder', $file->Parent()->Parent(), 'Grandparent folder is created in database');
// $this->assertFileExists($file->Parent()->Parent()->getFullPath(), 'Grandparent folder is created on filesystem');
// $this->assertEquals('assets', $file->Parent()->Parent()->Name);
}
2010-06-29 06:59:45 +02:00
function testGetExtension () {
$this -> assertEquals ( '' , File :: get_file_extension ( 'myfile' ), 'No extension' );
$this -> assertEquals ( 'txt' , File :: get_file_extension ( 'myfile.txt' ), 'Simple extension' );
$this -> assertEquals ( 'gz' , File :: get_file_extension ( 'myfile.tar.gz' ), 'Double-barrelled extension only returns last bit' );
}
2010-06-21 08:34:35 +02:00
function testValidateExtension () {
2010-06-29 06:59:45 +02:00
Session :: set ( 'loggedInAs' , null );
$origExts = File :: $allowed_extensions ;
File :: $allowed_extensions = array ( 'txt' );
$file = $this -> objFromFixture ( 'File' , 'asdf' );
// Invalid ext
2010-06-21 08:34:35 +02:00
$file -> Name = 'asdf.php' ;
$v = $file -> validate ();
$this -> assertFalse ( $v -> valid ());
$this -> assertContains ( 'Extension is not allowed' , $v -> message ());
2010-06-29 06:59:45 +02:00
// Valid ext
2010-06-21 08:34:35 +02:00
$file -> Name = 'asdf.txt' ;
$v = $file -> validate ();
$this -> assertTrue ( $v -> valid ());
2010-06-29 06:59:45 +02:00
2010-07-06 05:08:57 +02:00
// Capital extension is valid as well
$file -> Name = 'asdf.TXT' ;
$v = $file -> validate ();
$this -> assertTrue ( $v -> valid ());
2010-06-29 06:59:45 +02:00
File :: $allowed_extensions = $origExts ;
2010-06-21 08:34:35 +02:00
}
2010-06-29 06:59:48 +02:00
function testSetNameChangesFilesystemOnWrite () {
$file = $this -> objFromFixture ( 'File' , 'asdf' );
$oldPath = $file -> getFullPath ();
// Before write()
$file -> Name = 'renamed.txt' ;
$this -> assertFileExists ( $oldPath , 'Old path is still present' );
$this -> assertFileNotExists ( $file -> getFullPath (), 'New path is updated in memory, not written before write() is called' );
$file -> write ();
// After write()
clearstatcache ();
$this -> assertFileNotExists ( $oldPath , 'Old path is removed after write()' );
$this -> assertFileExists ( $file -> getFullPath (), 'New path is created after write()' );
}
function testSetParentIDChangesFilesystemOnWrite () {
$file = $this -> objFromFixture ( 'File' , 'asdf' );
$subfolder = $this -> objFromFixture ( 'Folder' , 'subfolder' );
$oldPath = $file -> getFullPath ();
// set ParentID
$file -> ParentID = $subfolder -> ID ;
// Before write()
$this -> assertFileExists ( $oldPath , 'Old path is still present' );
$this -> assertFileNotExists ( $file -> getFullPath (), 'New path is updated in memory, not written before write() is called' );
$file -> write ();
// After write()
clearstatcache ();
$this -> assertFileNotExists ( $oldPath , 'Old path is removed after write()' );
$this -> assertFileExists ( $file -> getFullPath (), 'New path is created after write()' );
}
/**
* @ see http :// open . silverstripe . org / ticket / 5693
*/
function testSetNameWithInvalidExtensionDoesntChangeFilesystem () {
$origExts = File :: $allowed_extensions ;
File :: $allowed_extensions = array ( 'txt' );
$file = $this -> objFromFixture ( 'File' , 'asdf' );
$oldPath = $file -> getFullPath ();
$file -> Name = 'renamed.php' ; // evil extension
try {
$file -> write ();
} catch ( ValidationException $e ) {
File :: $allowed_extensions = $origExts ;
return ;
}
$this -> fail ( 'Expected ValidationException not raised' );
File :: $allowed_extensions = $origExts ;
}
2008-08-25 03:42:27 +02:00
function testLinkAndRelativeLink () {
$file = $this -> objFromFixture ( 'File' , 'asdf' );
2010-06-29 06:59:47 +02:00
$this -> assertEquals ( ASSETS_DIR . '/FileTest.txt' , $file -> RelativeLink ());
$this -> assertEquals ( Director :: baseURL () . ASSETS_DIR . '/FileTest.txt' , $file -> Link ());
2008-08-25 03:42:27 +02:00
}
2010-06-29 06:59:48 +02:00
function testGetRelativePath () {
$rootfile = $this -> objFromFixture ( 'File' , 'asdf' );
$this -> assertEquals ( 'assets/FileTest.txt' , $rootfile -> getRelativePath (), 'File in assets/ folder' );
$subfolderfile = $this -> objFromFixture ( 'File' , 'subfolderfile' );
$this -> assertEquals ( 'assets/FileTest-subfolder/FileTestSubfolder.txt' , $subfolderfile -> getRelativePath (), 'File in subfolder within assets/ folder, with existing Filename' );
$subfolderfilesetfromname = $this -> objFromFixture ( 'File' , 'subfolderfile-setfromname' );
$this -> assertEquals ( 'assets/FileTest-subfolder/FileTestSubfolder2.txt' , $subfolderfilesetfromname -> getRelativePath (), 'File in subfolder within assets/ folder, with Filename generated through setName()' );
}
function testGetFullPath () {
$rootfile = $this -> objFromFixture ( 'File' , 'asdf' );
$this -> assertEquals ( ASSETS_PATH . '/FileTest.txt' , $rootfile -> getFullPath (), 'File in assets/ folder' );
}
2010-08-09 01:48:54 +02:00
function testGetURL () {
$rootfile = $this -> objFromFixture ( 'File' , 'asdf' );
$this -> assertEquals ( Director :: baseURL () . $rootfile -> getFilename (), $rootfile -> getURL ());
}
function testGetAbsoluteURL () {
$rootfile = $this -> objFromFixture ( 'File' , 'asdf' );
$this -> assertEquals ( Director :: absoluteBaseURL () . $rootfile -> getFilename (), $rootfile -> getAbsoluteURL ());
}
2008-08-25 03:42:27 +02:00
function testNameAndTitleGeneration () {
/* If objects are loaded into the system with just a Filename, then Name is generated but Title isn't */
$file = $this -> objFromFixture ( 'File' , 'asdf' );
2010-06-29 06:59:47 +02:00
$this -> assertEquals ( 'FileTest.txt' , $file -> Name );
2008-08-25 03:42:27 +02:00
$this -> assertNull ( $file -> Title );
/* However, if Name is set instead of Filename, then Title is set */
$file = $this -> objFromFixture ( 'File' , 'setfromname' );
2010-06-29 06:59:47 +02:00
$this -> assertEquals ( ASSETS_DIR . '/FileTest.png' , $file -> Filename );
$this -> assertEquals ( 'FileTest' , $file -> Title );
2008-08-25 03:42:27 +02:00
}
function testSizeAndAbsoluteSizeParameters () {
$file = $this -> objFromFixture ( 'File' , 'asdf' );
/* AbsoluteSize will give the integer number */
$this -> assertEquals ( 1000000 , $file -> AbsoluteSize );
/* Size will give a humanised number */
$this -> assertEquals ( '977 KB' , $file -> Size );
}
function testFileType () {
$file = $this -> objFromFixture ( 'File' , 'gif' );
2008-10-16 06:33:35 +02:00
$this -> assertEquals ( " GIF image - good for diagrams " , $file -> FileType );
2010-06-29 06:59:48 +02:00
2008-08-25 03:42:27 +02:00
$file = $this -> objFromFixture ( 'File' , 'pdf' );
$this -> assertEquals ( " Adobe Acrobat PDF file " , $file -> FileType );
2010-06-29 06:59:48 +02:00
2008-08-25 03:42:27 +02:00
/* Only a few file types are given special descriptions; the rest are unknown */
$file = $this -> objFromFixture ( 'File' , 'asdf' );
$this -> assertEquals ( " unknown " , $file -> FileType );
}
/**
* Test the File :: format_size () method
*/
function testFormatSize () {
$this -> assertEquals ( " 1000 bytes " , File :: format_size ( 1000 ));
$this -> assertEquals ( " 1023 bytes " , File :: format_size ( 1023 ));
$this -> assertEquals ( " 1 KB " , File :: format_size ( 1025 ));
$this -> assertEquals ( " 9.8 KB " , File :: format_size ( 10000 ));
$this -> assertEquals ( " 49 KB " , File :: format_size ( 50000 ));
$this -> assertEquals ( " 977 KB " , File :: format_size ( 1000000 ));
$this -> assertEquals ( " 1 MB " , File :: format_size ( 1024 * 1024 ));
$this -> assertEquals ( " 954 MB " , File :: format_size ( 1000000000 ));
$this -> assertEquals ( " 1 GB " , File :: format_size ( 1024 * 1024 * 1024 ));
$this -> assertEquals ( " 9.3 GB " , File :: format_size ( 10000000000 ));
// It use any denomination higher than GB. It also doesn't overflow with >32 bit integers
$this -> assertEquals ( " 93132.3 GB " , File :: format_size ( 100000000000000 ));
}
2010-06-29 06:59:48 +02:00
function testDeleteDatabaseOnly () {
$file = $this -> objFromFixture ( 'File' , 'asdf' );
$fileID = $file -> ID ;
$filePath = $file -> getFullPath ();
$file -> deleteDatabaseOnly ();
DataObject :: flush_and_destroy_cache ();
$this -> assertFileExists ( $filePath );
$this -> assertFalse ( DataObject :: get_by_id ( 'File' , $fileID ));
}
2008-08-25 03:42:27 +02:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
function setUp () {
parent :: setUp ();
2010-02-04 01:32:26 +01:00
if ( ! file_exists ( ASSETS_PATH )) mkdir ( ASSETS_PATH );
2008-08-25 03:42:27 +02:00
/* Create a test folders for each of the fixture references */
2010-06-29 06:59:47 +02:00
$folderIDs = $this -> allFixtureIDs ( 'Folder' );
foreach ( $folderIDs as $folderID ) {
$folder = DataObject :: get_by_id ( 'Folder' , $folderID );
if ( ! file_exists ( BASE_PATH . " / $folder->Filename " )) mkdir ( BASE_PATH . " / $folder->Filename " );
2008-08-25 03:42:27 +02:00
}
/* Create a test files for each of the fixture references */
$fileIDs = $this -> allFixtureIDs ( 'File' );
foreach ( $fileIDs as $fileID ) {
$file = DataObject :: get_by_id ( 'File' , $fileID );
2010-01-28 06:10:32 +01:00
$fh = fopen ( BASE_PATH . " / $file->Filename " , " w " );
2008-08-25 03:42:27 +02:00
fwrite ( $fh , str_repeat ( 'x' , 1000000 ));
fclose ( $fh );
}
}
function tearDown () {
2010-10-12 00:31:11 +02:00
parent :: tearDown ();
2008-08-25 03:42:27 +02:00
/* Remove the test files that we've created */
$fileIDs = $this -> allFixtureIDs ( 'File' );
foreach ( $fileIDs as $fileID ) {
$file = DataObject :: get_by_id ( 'File' , $fileID );
2010-06-29 06:59:47 +02:00
if ( $file && file_exists ( BASE_PATH . " / $file->Filename " )) unlink ( BASE_PATH . " / $file->Filename " );
2008-08-25 03:42:27 +02:00
}
/* Remove the test folders that we've crated */
2010-06-29 06:59:47 +02:00
$folderIDs = $this -> allFixtureIDs ( 'Folder' );
foreach ( $folderIDs as $folderID ) {
$folder = DataObject :: get_by_id ( 'Folder' , $folderID );
2010-06-29 06:59:48 +02:00
if ( $folder && file_exists ( BASE_PATH . " / $folder->Filename " )) Filesystem :: removeFolder ( BASE_PATH . " / $folder->Filename " );
2008-08-25 03:42:27 +02:00
}
2010-10-12 00:31:11 +02:00
// Remove left over folders and any files that may exist
if ( file_exists ( '../assets/FileTest' )) Filesystem :: removeFolder ( '../assets/FileTest' );
if ( file_exists ( '../assets/FileTest-subfolder' )) Filesystem :: removeFolder ( '../assets/FileTest-subfolder' );
if ( file_exists ( '../assets/FileTest.txt' )) unlink ( '../assets/FileTest.txt' );
2008-08-25 03:42:27 +02:00
}
2010-10-12 00:31:11 +02:00
2008-08-25 03:42:27 +02:00
}