3 namespace Drupal\KernelTests\Core\File;
5 use Drupal\Component\PhpStorage\FileStorage;
8 * Tests operations dealing with directories.
12 class DirectoryTest extends FileTestBase {
15 * Test local directory handling functions.
17 public function testFileCheckLocalDirectoryHandling() {
18 $site_path = $this->container->get('site.path');
19 $directory = $site_path . '/files';
21 // Check a new recursively created local directory for correct file system
23 $parent = $this->randomMachineName();
24 $child = $this->randomMachineName();
26 // Files directory already exists.
27 $this->assertTrue(is_dir($directory), t('Files directory already exists.'), 'File');
28 // Make files directory writable only.
29 $old_mode = fileperms($directory);
31 // Create the directories.
32 $parent_path = $directory . DIRECTORY_SEPARATOR . $parent;
33 $child_path = $parent_path . DIRECTORY_SEPARATOR . $child;
34 $this->assertTrue(drupal_mkdir($child_path, 0775, TRUE), t('No error reported when creating new local directories.'), 'File');
36 // Ensure new directories also exist.
37 $this->assertTrue(is_dir($parent_path), t('New parent directory actually exists.'), 'File');
38 $this->assertTrue(is_dir($child_path), t('New child directory actually exists.'), 'File');
40 // Check that new directory permissions were set properly.
41 $this->assertDirectoryPermissions($parent_path, 0775);
42 $this->assertDirectoryPermissions($child_path, 0775);
44 // Check that existing directory permissions were not modified.
45 $this->assertDirectoryPermissions($directory, $old_mode);
47 // Check creating a directory using an absolute path.
48 $absolute_path = \Drupal::service('file_system')->realpath($directory) . DIRECTORY_SEPARATOR . $this->randomMachineName() . DIRECTORY_SEPARATOR . $this->randomMachineName();
49 $this->assertTrue(drupal_mkdir($absolute_path, 0775, TRUE), 'No error reported when creating new absolute directories.', 'File');
50 $this->assertDirectoryPermissions($absolute_path, 0775);
54 * Test directory handling functions.
56 public function testFileCheckDirectoryHandling() {
57 // A directory to operate on.
58 $directory = file_default_scheme() . '://' . $this->randomMachineName() . '/' . $this->randomMachineName();
59 $this->assertFalse(is_dir($directory), 'Directory does not exist prior to testing.');
61 // Non-existent directory.
62 $this->assertFalse(file_prepare_directory($directory, 0), 'Error reported for non-existing directory.', 'File');
65 $this->assertTrue(file_prepare_directory($directory, FILE_CREATE_DIRECTORY), 'No error reported when creating a new directory.', 'File');
67 // Make sure directory actually exists.
68 $this->assertTrue(is_dir($directory), 'Directory actually exists.', 'File');
70 if (substr(PHP_OS, 0, 3) != 'WIN') {
71 // PHP on Windows doesn't support any kind of useful read-only mode for
72 // directories. When executing a chmod() on a directory, PHP only sets the
73 // read-only flag, which doesn't prevent files to actually be written
74 // in the directory on any recent version of Windows.
76 // Make directory read only.
77 @drupal_chmod($directory, 0444);
78 $this->assertFalse(file_prepare_directory($directory, 0), 'Error reported for a non-writeable directory.', 'File');
80 // Test directory permission modification.
81 $this->setSetting('file_chmod_directory', 0777);
82 $this->assertTrue(file_prepare_directory($directory, FILE_MODIFY_PERMISSIONS), 'No error reported when making directory writeable.', 'File');
85 // Test that the directory has the correct permissions.
86 $this->assertDirectoryPermissions($directory, 0777, 'file_chmod_directory setting is respected.');
88 // Remove .htaccess file to then test that it gets re-created.
89 @drupal_unlink(file_default_scheme() . '://.htaccess');
90 $this->assertFalse(is_file(file_default_scheme() . '://.htaccess'), 'Successfully removed the .htaccess file in the files directory.', 'File');
91 file_ensure_htaccess();
92 $this->assertTrue(is_file(file_default_scheme() . '://.htaccess'), 'Successfully re-created the .htaccess file in the files directory.', 'File');
93 // Verify contents of .htaccess file.
94 $file = file_get_contents(file_default_scheme() . '://.htaccess');
95 $this->assertEqual($file, FileStorage::htaccessLines(FALSE), 'The .htaccess file contains the proper content.', 'File');
99 * This will take a directory and path, and find a valid filepath that is not
100 * taken by another file.
102 public function testFileCreateNewFilepath() {
103 // First we test against an imaginary file that does not exist in a
105 $basename = 'xyz.txt';
106 $directory = 'core/misc';
107 $original = $directory . '/' . $basename;
108 $path = file_create_filename($basename, $directory);
109 $this->assertEqual($path, $original, format_string('New filepath %new equals %original.', ['%new' => $path, '%original' => $original]), 'File');
111 // Then we test against a file that already exists within that directory.
112 $basename = 'druplicon.png';
113 $original = $directory . '/' . $basename;
114 $expected = $directory . '/druplicon_0.png';
115 $path = file_create_filename($basename, $directory);
116 $this->assertEqual($path, $expected, format_string('Creating a new filepath from %original equals %new (expected %expected).', ['%new' => $path, '%original' => $original, '%expected' => $expected]), 'File');
118 // @TODO: Finally we copy a file into a directory several times, to ensure a properly iterating filename suffix.
122 * This will test the filepath for a destination based on passed flags and
123 * whether or not the file exists.
125 * If a file exists, file_destination($destination, $replace) will either
127 * - the existing filepath, if $replace is FILE_EXISTS_REPLACE
128 * - a new filepath if FILE_EXISTS_RENAME
129 * - an error (returning FALSE) if FILE_EXISTS_ERROR.
130 * If the file doesn't currently exist, then it will simply return the
133 public function testFileDestination() {
134 // First test for non-existent file.
135 $destination = 'core/misc/xyz.txt';
136 $path = file_destination($destination, FILE_EXISTS_REPLACE);
137 $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_REPLACE.', 'File');
138 $path = file_destination($destination, FILE_EXISTS_RENAME);
139 $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_RENAME.', 'File');
140 $path = file_destination($destination, FILE_EXISTS_ERROR);
141 $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_ERROR.', 'File');
143 $destination = 'core/misc/druplicon.png';
144 $path = file_destination($destination, FILE_EXISTS_REPLACE);
145 $this->assertEqual($path, $destination, 'Existing filepath destination remains the same with FILE_EXISTS_REPLACE.', 'File');
146 $path = file_destination($destination, FILE_EXISTS_RENAME);
147 $this->assertNotEqual($path, $destination, 'A new filepath destination is created when filepath destination already exists with FILE_EXISTS_RENAME.', 'File');
148 $path = file_destination($destination, FILE_EXISTS_ERROR);
149 $this->assertEqual($path, FALSE, 'An error is returned when filepath destination already exists with FILE_EXISTS_ERROR.', 'File');
153 * Ensure that the file_directory_temp() function always returns a value.
155 public function testFileDirectoryTemp() {
156 // Start with an empty variable to ensure we have a clean slate.
157 $config = $this->config('system.file');
158 $config->set('path.temporary', '')->save();
159 $tmp_directory = file_directory_temp();
160 $this->assertEqual(empty($tmp_directory), FALSE, 'file_directory_temp() returned a non-empty value.');
161 $this->assertEqual($config->get('path.temporary'), $tmp_directory);
165 * Tests directory creation.
167 public function testDirectoryCreation() {
168 /** @var \Drupal\Core\File\FileSystemInterface $file_system */
169 $file_system = $this->container->get('file_system');
171 // mkdir() recursion should work with or without a trailing slash.
172 $dir = $this->siteDirectory . '/files';
173 $this->assertTrue($file_system->mkdir($dir . '/foo/bar', 0775, TRUE));
174 $this->assertTrue($file_system->mkdir($dir . '/foo/baz/', 0775, TRUE));