? .DS_Store ? .cache ? .git ? .project ? .settings ? empty ? file_203204_2.patch ? logs ? test.php ? sites/all/modules ? sites/default/files ? sites/default/settings.php ? sites/default/test Index: includes/file.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/file.inc,v retrieving revision 1.133 diff -u -p -r1.133 file.inc --- includes/file.inc 17 Sep 2008 07:11:56 -0000 1.133 +++ includes/file.inc 18 Sep 2008 01:14:28 -0000 @@ -646,6 +646,11 @@ function file_save_upload($source, $vali $file->timestamp = REQUEST_TIME; drupal_write_record('files', $file); + // Give everyone read access so that FTP'd users or non-webserver users + // can see/read these files, and give group write permissions so group + // members can alter files uploaded by the webserver. + @chmod($file->filepath, 0664); + // Add file to the cache. $upload_cache[$source] = $file; return $file; Index: modules/simpletest/tests/file.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/file.test,v retrieving revision 1.4 diff -u -p -r1.4 file.test --- modules/simpletest/tests/file.test 17 Sep 2008 07:11:58 -0000 1.4 +++ modules/simpletest/tests/file.test 18 Sep 2008 01:14:30 -0000 @@ -15,6 +15,79 @@ function file_test_validator($file, $err } /** + * Base class for file tests that adds some additional file specific + * assertions and helper functions. + */ +class FileTestCase extends DrupalWebTestCase { + /** + * Helper function to test the permissions of a file. + * + * @param $filepath + * String file path. + * @param $mode + * Octal integer like 0664 or 0777. + * @param $message + * Optional message. + */ + function assertPermissions($filepath, $expected_mode, $message = NULL) { + // Mask out all but the last three octets. + $actual_mode = fileperms($filepath) & 511; + if (is_null($message)) { + $message = t(($actual_mode == $expected_mode) ? "File permissions set correctly." : "Expected file permission to be %expected, actually were %actual.", array('%actual' => decoct($actual_mode), '%expected' => decoct($expected_mode))); + } + $this->assertEqual($actual_mode, $expected_mode, $message); + } + + /** + * Create a directory and assert it exists. + * + * @param $path + * Optional string with a directory path. If none is provided, a random + * name in the site's files directory will be used. + * @return + * The path to the directory. + */ + function createDirectory($path = NULL) { + // A directory to operate on. + if (is_null($path)) { + $path = file_directory_path() . '/' . $this->randomName(); + } + $this->assertTrue(mkdir($path) && is_dir($path), t('Directory was created successfully.')); + return $path; + } + + /** + * Create a file and save it to the files table and assert that it occurs + * correctly. + * + * @param $filepath + * Optional string specifying the file path. If none is provided then a + * randomly named file will be created in the site's files directory. + * @return + * File object. + */ + function createFile($filepath = NULL) { + if (is_null($filepath)) { + $filepath = file_directory_path() . '/' . $this->randomName(); + } + + touch($filepath); + $this->assertTrue(is_file($filepath), t("The test file exists on the disk.")); + + $f = new stdClass(); + $f->filepath = $filepath; + $f->filename = basename($f->filepath); + $f->filemime = 'text/plain'; + $f->uid = 1; + $f->timestamp = REQUEST_TIME; + $f->filesize = 0; + $this->assertNotIdentical(drupal_write_record('files', $f), FALSE, t("The file was added to the database.")); + + return $f; + } +} + +/** * This will run tests against the file validation functions (file_validate_*). */ class FileValidateTest extends DrupalWebTestCase { @@ -193,19 +266,17 @@ class FileValidateTest extends DrupalWeb } } - /** - * This will run tests against file validation. - * + * Tests the file_save_data() function. */ -class FileLoadSaveTest extends DrupalWebTestCase { +class FileSaveDataTest extends FileTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( - 'name' => t('File loading and saving'), - 'description' => t('Tests the file loading and saving functions.'), + 'name' => t('File save'), + 'description' => t('Tests the file save data function.'), 'group' => t('File'), ); } @@ -225,6 +296,54 @@ class FileLoadSaveTest extends DrupalWeb $this->assertEqual(file_directory_path(), dirname($filepath), t("File was placed in Drupal's files directory.")); $this->assertEqual('asdf.txt', basename($filepath), t("File was named correctly.")); $this->assertEqual($contents, file_get_contents(realpath($filepath)), t("Contents of the file are correct.")); + $this->assertPermissions($filepath, 0664); + } +} + +/** + * This will run tests against file validation. + * + */ +class FileSaveUploadTest extends FileTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('File uploading'), + 'description' => t('Tests the file uploading functions.'), + 'group' => t('File'), + ); + } + + /** + * Implementation of setUp(). + */ + function setUp() { + // Need to enable the test module for an upload target. + parent::setUp('file_test'); + } + + function testFileSaveUpload() { + $max_fid_before = db_result(db_query("SELECT MAX(fid) AS fid FROM {files}")); + + $upload_user = $this->drupalCreateUser(array('access content')); + $this->drupalLogin($upload_user); + + $image = current($this->drupalGetTestFiles('image')); + $this->assertTrue(is_file($image->filename), t("The file we're going to upload exists.")); + $edit = array('files[file_test_upload]' => realpath($image->filename)); + $this->drupalPost('file-test/upload', $edit, t('Submit')); + $this->assertResponse(200, t("Received a 200 response for posted test file.")); + + $max_fid_after = db_result(db_query("SELECT MAX(fid) AS fid FROM {files}")); + $this->assertTrue($max_fid_after > $max_fid_before, t("A new file was created.")); + + // FIXME this is some stupidity because we don't have a file_load(). + // Replace this once the hook_file patch gets committed in 2010. + $file = db_fetch_object(db_query('SELECT f.* FROM {files} f WHERE f.fid = %d', array($max_fid_after))); + $this->assertTrue($file, t("Loaded the file.")); + $this->assertPermissions($file->filepath, 0664); } } @@ -398,47 +517,25 @@ class FileDirectoryTest extends DrupalWe /** * Deletion related tests */ -class FileCopyDeleteMoveTest extends DrupalWebTestCase { +class FileDeleteTest extends FileTestCase { /** * Implementation of getInfo(). */ function getInfo() { return array( - 'name' => t('File management'), - 'description' => t('Tests the file copy, delete and move functions.'), + 'name' => t('File delete'), + 'description' => t('Tests the file delete function.'), 'group' => t('File'), ); } - /** - * Implementation of setUp(). - */ - function setUp() { - // Install file_test module - parent::setUp(); - - // A directory to operate on. - $this->dirname = file_directory_path() . '/' . $this->randomName(); - mkdir($this->dirname); - + function testFileDelete() { // Create a file for testing - $f = new stdClass(); - $f->filepath = file_directory_path() . '/' . $this->randomName(); - $f->filename = basename($f->filepath); - touch($f->filepath); - $f->filemime = 'text/plain'; - $f->uid = 1; - $f->timestamp = REQUEST_TIME; - $f->filesize = 0; - drupal_write_record('files', $f); - $this->file = $f; - } + $file = $this->createFile(); - function testFileDelete() { // Delete a regular file - $this->assertTrue(is_file($this->file->filepath), t("File exists.")); - $this->assertTrue(file_delete($this->file->filepath), t("Deleted worked.")); - $this->assertFalse(file_exists($this->file->filepath), t("Test file has actually been deleted.")); + $this->assertTrue(file_delete($file->filepath), t("Deleted worked.")); + $this->assertFalse(file_exists($file->filepath), t("Test file has actually been deleted.")); } function testFileDelete_Missing() { @@ -447,21 +544,43 @@ class FileCopyDeleteMoveTest extends Dru } function testFileDelete_Directory() { + // A directory to operate on. + $this->dirname = $this->createDirectory(); + // Try to delete a directory - $this->assertTrue(is_dir($this->dirname), t("Directory exists.")); $this->assertFalse(file_delete($this->dirname), t("Could not delete the delete directory.")); $this->assertTrue(file_exists($this->dirname), t("Directory has not been deleted.")); } +} + + +/** + * Move related tests + */ +class FileMoveTest extends FileTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('File moving'), + 'description' => t('Tests the file move function.'), + 'group' => t('File'), + ); + } function testFileMove() { + // Create a file for testing + $file = $this->createFile(); + // Moving to a new name. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before moving.")); $desired_filepath = file_directory_path() . '/' . $this->randomName(); - $new_filepath = file_move($this->file->filepath, $desired_filepath, FILE_EXISTS_ERROR); + $new_filepath = file_move($file->filepath, $desired_filepath, FILE_EXISTS_ERROR); $this->assertTrue($new_filepath, t("Move was successful.")); $this->assertEqual($new_filepath, $desired_filepath, t("Returned expected filepath.")); $this->assertTrue(file_exists($new_filepath), t("File exists at the new location.")); - $this->assertFalse(file_exists($this->file->filepath), t("No file remains at the old location.")); + $this->assertFalse(file_exists($file->filepath), t("No file remains at the old location.")); + $this->assertPermissions($new_filepath, 0664); // Moving with rename. $desired_filepath = file_directory_path() . '/' . $this->randomName(); @@ -472,6 +591,7 @@ class FileCopyDeleteMoveTest extends Dru $this->assertNotEqual($newer_filepath, $desired_filepath, t("Returned expected filepath.")); $this->assertTrue(file_exists($newer_filepath), t("File exists at the new location.")); $this->assertFalse(file_exists($new_filepath), t("No file remains at the old location.")); + $this->assertPermissions($newer_filepath, 0664); // TODO: test moving to a directory (rather than full directory/file path) } @@ -485,21 +605,50 @@ class FileCopyDeleteMoveTest extends Dru } function testFileMove_OverwriteSelf() { + // Create a file for testing + $file = $this->createFile(); + // Move the file onto itself without renaming shouldn't make changes. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before moving.")); - $new_filepath = file_move($this->file->filepath, $this->file->filepath, FILE_EXISTS_REPLACE); + $new_filepath = file_move($file->filepath, $file->filepath, FILE_EXISTS_REPLACE); $this->assertFalse($new_filepath, t("Moving onto itself without renaming fails.")); - $this->assertTrue(file_exists($this->file->filepath), t("File exists after moving onto itself.")); + $this->assertTrue(file_exists($file->filepath), t("File exists after moving onto itself.")); // Move the file onto itself with renaming will result in a new filename. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before moving.")); - $new_filepath = file_move($this->file->filepath, $this->file->filepath, FILE_EXISTS_RENAME); + $new_filepath = file_move($file->filepath, $file->filepath, FILE_EXISTS_RENAME); $this->assertTrue($new_filepath, t("Moving onto itself with renaming works.")); - $this->assertFalse(file_exists($this->file->filepath), t("Original file has been removed.")); + $this->assertFalse(file_exists($file->filepath), t("Original file has been removed.")); $this->assertTrue(file_exists($new_filepath), t("File exists after moving onto itself.")); drupal_get_messages(); } +} + + +/** + * Move related tests + */ +class FileCopyTest extends FileTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('File copying'), + 'description' => t('Tests the file copy function.'), + 'group' => t('File'), + ); + } + + /** + * Implementation of setUp(). + */ + function setUp() { + // Install file_test module + parent::setUp(); + + // Create a file for testing + $this->file = $this->createFile(); + } function testFileCopy() { // Copying to a new name. @@ -509,6 +658,7 @@ class FileCopyDeleteMoveTest extends Dru $this->assertEqual($new_filepath, $desired_filepath, t("Returned expected filepath.")); $this->assertTrue(file_exists($this->file->filepath), t("Original file remains.")); $this->assertTrue(file_exists($new_filepath), t("New file exists.")); + $this->assertPermissions($new_filepath, 0664); // Copying with rename. $desired_filepath = file_directory_path() . '/' . $this->randomName(); @@ -518,6 +668,7 @@ class FileCopyDeleteMoveTest extends Dru $this->assertNotEqual($newer_filepath, $desired_filepath, t("Returned expected filepath.")); $this->assertTrue(file_exists($this->file->filepath), t("Original file remains.")); $this->assertTrue(file_exists($new_filepath), t("New file exists.")); + $this->assertPermissions($new_filepath, 0664); // TODO: test copying to a directory (rather than full directory/file path) } @@ -534,7 +685,6 @@ class FileCopyDeleteMoveTest extends Dru function testFileCopy_OverwriteSelf() { // Copy the file onto itself with renaming works. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before copying.")); $new_filepath = file_copy($this->file->filepath, $this->file->filepath, FILE_EXISTS_RENAME); $this->assertTrue($new_filepath, t("Copying onto itself with renaming works.")); $this->assertNotEqual($new_filepath, $this->file->filepath, t("Copied file has a new name.")); @@ -542,19 +692,16 @@ class FileCopyDeleteMoveTest extends Dru $this->assertTrue(file_exists($new_filepath), t("Copied file exists after copying onto itself.")); // Copy the file onto itself without renaming fails. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before copying.")); $new_filepath = file_copy($this->file->filepath, $this->file->filepath, FILE_EXISTS_ERROR); $this->assertFalse($new_filepath, t("Copying onto itself without renaming fails.")); $this->assertTrue(file_exists($this->file->filepath), t("File exists after copying onto itself.")); // Copy the file into same directory without renaming fails. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before copying.")); $new_filepath = file_copy($this->file->filepath, dirname($this->file->filepath), FILE_EXISTS_ERROR); $this->assertFalse($new_filepath, t("Copying onto itself fails.")); $this->assertTrue(file_exists($this->file->filepath), t("File exists after copying onto itself.")); // Copy the file into same directory with renaming works. - $this->assertTrue(file_exists($this->file->filepath), t("File exists before copying.")); $new_filepath = file_copy($this->file->filepath, dirname($this->file->filepath), FILE_EXISTS_RENAME); $this->assertTrue($new_filepath, t("Copying into same directory works.")); $this->assertNotEqual($new_filepath, $this->file->filepath, t("Copied file has a new name.")); Index: modules/simpletest/tests/file_test.info =================================================================== RCS file: modules/simpletest/tests/file_test.info diff -N modules/simpletest/tests/file_test.info --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/tests/file_test.info 18 Sep 2008 01:14:30 -0000 @@ -0,0 +1,8 @@ +; $Id$ +name = "File test" +description = "Support module for file handling tests." +package = Testing +version = VERSION +core = 7.x +files[] = file_test.module +;hidden = TRUE Index: modules/simpletest/tests/file_test.module =================================================================== RCS file: modules/simpletest/tests/file_test.module diff -N modules/simpletest/tests/file_test.module --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/tests/file_test.module 18 Sep 2008 01:14:30 -0000 @@ -0,0 +1,53 @@ + t('Upload test'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('_file_test_form'), + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + return $items; +} + +/** + * Form to test file uploads. + */ +function _file_test_form(&$form_state) { + $form['#attributes'] = array('enctype' => 'multipart/form-data'); + $form['file_test_upload'] = array( + '#type' => 'file', + '#title' => t('Upload an image'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Submit'), + ); + return $form; +} + +/** + * Process the upload. + */ +function _file_test_form_submit(&$form, &$form_state) { + // Validate the uploaded picture. + $file = file_save_upload('file_test_upload', array('file_validate_is_image' => array())); + if ($file) { + $form_state['values']['file_test_upload'] = $file; + drupal_set_message(t('File "@filepath was uploaded.', array('@filepath' => $file->filepath))); + } + else { + drupal_set_message(t('Epic upload FAIL!'), 'error'); + } +} \ No newline at end of file