PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/filesystem/FolderTest.php

http://github.com/silverstripe/sapphire
PHP | 239 lines | 161 code | 44 blank | 34 comment | 0 complexity | 4fecb29a5febb817c0da7b8bca28b351 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. use Filesystem as SS_Filesystem;
  3. use SilverStripe\ORM\Versioning\Versioned;
  4. use SilverStripe\ORM\DataObject;
  5. /**
  6. * @author Ingo Schommer (ingo at silverstripe dot com)
  7. *
  8. * @package framework
  9. * @subpackage tests
  10. */
  11. class FolderTest extends SapphireTest {
  12. protected static $fixture_file = 'FileTest.yml';
  13. public function setUp() {
  14. parent::setUp();
  15. $this->logInWithPermission('ADMIN');
  16. Versioned::set_stage(Versioned::DRAFT);
  17. // Set backend root to /FolderTest
  18. AssetStoreTest_SpyStore::activate('FolderTest');
  19. // Set the File Name Filter replacements so files have the expected names
  20. Config::inst()->update('FileNameFilter', 'default_replacements', array(
  21. '/\s/' => '-', // remove whitespace
  22. '/_/' => '-', // underscores to dashes
  23. '/[^A-Za-z0-9+.\-]+/' => '', // remove non-ASCII chars, only allow alphanumeric plus dash and dot
  24. '/[\-]{2,}/' => '-', // remove duplicate dashes
  25. '/^[\.\-_]+/' => '', // Remove all leading dots, dashes or underscores
  26. ));
  27. // Create a test folders for each of the fixture references
  28. foreach(Folder::get() as $folder) {
  29. $path = AssetStoreTest_SpyStore::getLocalPath($folder);
  30. SS_Filesystem::makeFolder($path);
  31. }
  32. // Create a test files for each of the fixture references
  33. $files = File::get()->exclude('ClassName', 'Folder');
  34. foreach($files as $file) {
  35. $path = AssetStoreTest_SpyStore::getLocalPath($file);
  36. SS_Filesystem::makeFolder(dirname($path));
  37. $fh = fopen($path, "w+");
  38. fwrite($fh, str_repeat('x', 1000000));
  39. fclose($fh);
  40. }
  41. }
  42. public function tearDown() {
  43. AssetStoreTest_SpyStore::reset();
  44. parent::tearDown();
  45. }
  46. public function testCreateFromNameAndParentIDSetsFilename() {
  47. $folder1 = $this->objFromFixture('Folder', 'folder1');
  48. $newFolder = new Folder();
  49. $newFolder->Name = 'CreateFromNameAndParentID';
  50. $newFolder->ParentID = $folder1->ID;
  51. $newFolder->write();
  52. $this->assertEquals($folder1->Filename . 'CreateFromNameAndParentID/', $newFolder->Filename);
  53. }
  54. public function testAllChildrenIncludesFolders() {
  55. $folder1 = $this->objFromFixture('Folder', 'folder1');
  56. $subfolder1 = $this->objFromFixture('Folder', 'folder1-subfolder1');
  57. $file1 = $this->objFromFixture('File', 'file1-folder1');
  58. $children = $folder1->allChildren();
  59. $this->assertEquals(2, $children->Count());
  60. $this->assertContains($subfolder1->ID, $children->column('ID'));
  61. $this->assertContains($file1->ID, $children->column('ID'));
  62. }
  63. public function testFindOrMake() {
  64. $path = 'parent/testFindOrMake/';
  65. $folder = Folder::find_or_make($path);
  66. $this->assertEquals(
  67. ASSETS_PATH . '/FolderTest/' . $path,
  68. AssetStoreTest_SpyStore::getLocalPath($folder),
  69. 'Nested path information is correctly saved to database (with trailing slash)'
  70. );
  71. // Folder does not exist until it contains files
  72. $this->assertFileNotExists(
  73. AssetStoreTest_SpyStore::getLocalPath($folder),
  74. 'Empty folder does not have a filesystem record automatically'
  75. );
  76. $parentFolder = DataObject::get_one('Folder', array(
  77. '"File"."Name"' => 'parent'
  78. ));
  79. $this->assertNotNull($parentFolder);
  80. $this->assertEquals($parentFolder->ID, $folder->ParentID);
  81. $path = 'parent/testFindOrMake'; // no trailing slash
  82. $folder = Folder::find_or_make($path);
  83. $this->assertEquals(
  84. ASSETS_PATH . '/FolderTest/' . $path . '/', // Slash is automatically added here
  85. AssetStoreTest_SpyStore::getLocalPath($folder),
  86. 'Path information is correctly saved to database (without trailing slash)'
  87. );
  88. $path = 'assets/'; // relative to "assets/" folder, should produce "assets/assets/"
  89. $folder = Folder::find_or_make($path);
  90. $this->assertEquals(
  91. ASSETS_PATH . '/FolderTest/' . $path,
  92. AssetStoreTest_SpyStore::getLocalPath($folder),
  93. 'A folder named "assets/" within "assets/" is allowed'
  94. );
  95. }
  96. /**
  97. * Tests for the bug #5994 - Moving folder after executing Folder::findOrMake will not set the Filenames properly
  98. */
  99. public function testFindOrMakeFolderThenMove() {
  100. $folder1 = $this->objFromFixture('Folder', 'folder1');
  101. Folder::find_or_make($folder1->Filename);
  102. $folder2 = $this->objFromFixture('Folder', 'folder2');
  103. // Publish file1
  104. /** @var File $file1 */
  105. $file1 = DataObject::get_by_id('File', $this->idFromFixture('File', 'file1-folder1'), false);
  106. $file1->publishRecursive();
  107. // set ParentID. This should cause updateFilesystem to be called on all children
  108. $folder1->ParentID = $folder2->ID;
  109. $folder1->write();
  110. // Check if the file in the folder moved along
  111. /** @var File $file1Draft */
  112. $file1Draft = Versioned::get_by_stage('File', Versioned::DRAFT)->byID($file1->ID);
  113. $this->assertFileExists(AssetStoreTest_SpyStore::getLocalPath($file1Draft));
  114. $this->assertEquals(
  115. 'FileTest-folder2/FileTest-folder1/File1.txt',
  116. $file1Draft->Filename,
  117. 'The file DataObject has updated path'
  118. );
  119. // File should be located in new folder
  120. $this->assertEquals(
  121. ASSETS_PATH . '/FolderTest/.protected/FileTest-folder2/FileTest-folder1/55b443b601/File1.txt',
  122. AssetStoreTest_SpyStore::getLocalPath($file1Draft)
  123. );
  124. // Published (live) version remains in the old location
  125. /** @var File $file1Live */
  126. $file1Live = Versioned::get_by_stage('File', Versioned::LIVE)->byID($file1->ID);
  127. $this->assertEquals(
  128. ASSETS_PATH . '/FolderTest/FileTest-folder1/55b443b601/File1.txt',
  129. AssetStoreTest_SpyStore::getLocalPath($file1Live)
  130. );
  131. // Publishing the draft to live should move the new file to the public store
  132. $file1Draft->publishRecursive();
  133. $this->assertEquals(
  134. ASSETS_PATH . '/FolderTest/FileTest-folder2/FileTest-folder1/55b443b601/File1.txt',
  135. AssetStoreTest_SpyStore::getLocalPath($file1Draft)
  136. );
  137. }
  138. /**
  139. * Tests for the bug #5994 - if you don't execute get_by_id prior to the rename or move, it will fail.
  140. */
  141. public function testRenameFolderAndCheckTheFile() {
  142. // ID is prefixed in case Folder is subclassed by project/other module.
  143. $folder1 = DataObject::get_one('Folder', array(
  144. '"File"."ID"' => $this->idFromFixture('Folder', 'folder1')
  145. ));
  146. $folder1->Name = 'FileTest-folder1-changed';
  147. $folder1->write();
  148. // Check if the file in the folder moved along
  149. $file1 = DataObject::get_by_id('File', $this->idFromFixture('File', 'file1-folder1'), false);
  150. $this->assertFileExists(
  151. AssetStoreTest_SpyStore::getLocalPath($file1)
  152. );
  153. $this->assertEquals(
  154. $file1->Filename,
  155. 'FileTest-folder1-changed/File1.txt',
  156. 'The file DataObject path uses renamed folder'
  157. );
  158. // File should be located in new folder
  159. $this->assertEquals(
  160. ASSETS_PATH . '/FolderTest/.protected/FileTest-folder1-changed/55b443b601/File1.txt',
  161. AssetStoreTest_SpyStore::getLocalPath($file1)
  162. );
  163. }
  164. /**
  165. * URL and Link are undefined for folder dataobjects
  166. */
  167. public function testLinkAndRelativeLink() {
  168. $folder = $this->objFromFixture('Folder', 'folder1');
  169. $this->assertEmpty($folder->getURL());
  170. $this->assertEmpty($folder->Link());
  171. }
  172. public function testIllegalFilenames() {
  173. // Test that generating a filename with invalid characters generates a correctly named folder.
  174. $folder = Folder::find_or_make('/FolderTest/EN_US Lang');
  175. $this->assertEquals('FolderTest/EN-US-Lang/', $folder->getFilename());
  176. // Test repeatitions of folder
  177. $folder2 = Folder::find_or_make('/FolderTest/EN_US Lang');
  178. $this->assertEquals($folder->ID, $folder2->ID);
  179. $folder3 = Folder::find_or_make('/FolderTest/EN--US_L!ang');
  180. $this->assertEquals($folder->ID, $folder3->ID);
  181. $folder4 = Folder::find_or_make('/FolderTest/EN-US-Lang');
  182. $this->assertEquals($folder->ID, $folder4->ID);
  183. }
  184. public function testTitleTiedToName() {
  185. $newFolder = new Folder();
  186. $newFolder->Name = 'TestNameCopiedToTitle';
  187. $this->assertEquals($newFolder->Name, $newFolder->Title);
  188. $newFolder->Title = 'TestTitleCopiedToName';
  189. $this->assertEquals($newFolder->Name, $newFolder->Title);
  190. $newFolder->Name = 'TestNameWithIllegalCharactersCopiedToTitle <!BANG!>';
  191. $this->assertEquals($newFolder->Name, $newFolder->Title);
  192. $newFolder->Title = 'TestTitleWithIllegalCharactersCopiedToName <!BANG!>';
  193. $this->assertEquals($newFolder->Name, $newFolder->Title);
  194. }
  195. }