Completed
Push — master ( 2fdc96...4f1f24 )
by Damian
12:09
created

FolderTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8
Metric Value
wmc 12
lcom 1
cbo 8
dl 0
loc 195
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A testLinkAndRelativeLink() 0 5 1
B setUp() 0 25 3
A tearDown() 0 4 1
A testCreateFromNameAndParentIDSetsFilename() 0 9 1
A testAllChildrenIncludesFolders() 0 10 1
B testFindOrMake() 0 37 1
B testFindOrMakeFolderThenMove() 0 25 1
B testRenameFolderAndCheckTheFile() 0 26 1
A testIllegalFilenames() 0 16 1
A testTitleTiedToName() 0 15 1
1
<?php
2
3
use Filesystem as SS_Filesystem;
4
5
/**
6
 * @author Ingo Schommer (ingo at silverstripe dot com)
7
 *
8
 * @package framework
9
 * @subpackage tests
10
 */
11
class FolderTest extends SapphireTest {
12
13
	protected static $fixture_file = 'FileTest.yml';
14
15
	public function setUp() {
16
		parent::setUp();
17
18
		$this->logInWithPermission('ADMIN');
19
		Versioned::reading_stage('Stage');
20
21
		// Set backend root to /FolderTest
22
		AssetStoreTest_SpyStore::activate('FolderTest');
23
24
		// Create a test folders for each of the fixture references
25
		foreach(Folder::get() as $folder) {
26
			$path = AssetStoreTest_SpyStore::getLocalPath($folder);
27
			SS_Filesystem::makeFolder($path);
28
		}
29
30
		// Create a test files for each of the fixture references
31
		$files = File::get()->exclude('ClassName', 'Folder');
32
		foreach($files as $file) {
33
			$path = AssetStoreTest_SpyStore::getLocalPath($file);
34
			SS_Filesystem::makeFolder(dirname($path));
35
			$fh = fopen($path, "w+");
36
			fwrite($fh, str_repeat('x', 1000000));
37
			fclose($fh);
38
		}
39
	}
40
41
	public function tearDown() {
42
		AssetStoreTest_SpyStore::reset();
43
		parent::tearDown();
44
	}
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
53
		$this->assertEquals($folder1->Filename . 'CreateFromNameAndParentID/', $newFolder->Filename);
54
	}
55
56
	public function testAllChildrenIncludesFolders() {
57
		$folder1 = $this->objFromFixture('Folder', 'folder1');
58
		$subfolder1 = $this->objFromFixture('Folder', 'folder1-subfolder1');
59
		$file1 = $this->objFromFixture('File', 'file1-folder1');
60
61
		$children = $folder1->allChildren();
62
		$this->assertEquals(2, $children->Count());
63
		$this->assertContains($subfolder1->ID, $children->column('ID'));
64
		$this->assertContains($file1->ID, $children->column('ID'));
65
	}
66
67
	public function testFindOrMake() {
68
		$path = 'parent/testFindOrMake/';
69
		$folder = Folder::find_or_make($path);
70
		$this->assertEquals(
71
			ASSETS_PATH . '/FolderTest/' . $path,
72
			AssetStoreTest_SpyStore::getLocalPath($folder),
73
			'Nested path information is correctly saved to database (with trailing slash)'
74
		);
75
76
		// Folder does not exist until it contains files
77
		$this->assertFileNotExists(
78
			AssetStoreTest_SpyStore::getLocalPath($folder),
79
			'Empty folder does not have a filesystem record automatically'
80
		);
81
		
82
		$parentFolder = DataObject::get_one('Folder', array(
83
			'"File"."Name"' => 'parent'
84
		));
85
		$this->assertNotNull($parentFolder);
86
		$this->assertEquals($parentFolder->ID, $folder->ParentID);
87
88
		$path = 'parent/testFindOrMake'; // no trailing slash
89
		$folder = Folder::find_or_make($path);
90
		$this->assertEquals(
91
			ASSETS_PATH . '/FolderTest/' . $path . '/', // Slash is automatically added here
92
			AssetStoreTest_SpyStore::getLocalPath($folder),
93
			'Path information is correctly saved to database (without trailing slash)'
94
		);
95
96
		$path = 'assets/'; // relative to "assets/" folder, should produce "assets/assets/"
97
		$folder = Folder::find_or_make($path);
98
		$this->assertEquals(
99
			ASSETS_PATH . '/FolderTest/' . $path,
100
			AssetStoreTest_SpyStore::getLocalPath($folder),
101
			'A folder named "assets/" within "assets/" is allowed'
102
		);
103
	}
104
105
	/**
106
	 * Tests for the bug #5994 - Moving folder after executing Folder::findOrMake will not set the Filenames properly
107
	 */
108
	public function testFindOrMakeFolderThenMove() {
109
		$folder1 = $this->objFromFixture('Folder', 'folder1');
110
		Folder::find_or_make($folder1->Filename);
111
		$folder2 = $this->objFromFixture('Folder', 'folder2');
112
113
		// set ParentID. This should cause updateFilesystem to be called on all children
114
		$folder1->ParentID = $folder2->ID;
0 ignored issues
show
Documentation introduced by
The property ParentID does not exist on object<DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
115
		$folder1->write();
116
117
		// Check if the file in the folder moved along
118
		$file1 = DataObject::get_by_id('File', $this->idFromFixture('File', 'file1-folder1'), false);
119
		$this->assertFileExists(AssetStoreTest_SpyStore::getLocalPath($file1));
120
		
121
		$this->assertEquals(
122
			'FileTest-folder2/FileTest-folder1/File1.txt',
123
			$file1->Filename,
124
			'The file DataObject has updated path'
125
		);
126
127
		// File should be located in new folder
128
		$this->assertEquals(
129
			ASSETS_PATH . '/FolderTest/.protected/FileTest-folder2/FileTest-folder1/55b443b601/File1.txt',
130
			AssetStoreTest_SpyStore::getLocalPath($file1)
131
		);
132
	}
133
134
	/**
135
	 * Tests for the bug #5994 - if you don't execute get_by_id prior to the rename or move, it will fail.
136
	 */
137
	public function testRenameFolderAndCheckTheFile() {
138
		// ID is prefixed in case Folder is subclassed by project/other module.
139
		$folder1 = DataObject::get_one('Folder', array(
140
			'"File"."ID"' => $this->idFromFixture('Folder', 'folder1')
141
		));
142
143
		$folder1->Name = 'FileTest-folder1-changed';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
144
		$folder1->write();
145
146
		// Check if the file in the folder moved along
147
		$file1 = DataObject::get_by_id('File', $this->idFromFixture('File', 'file1-folder1'), false);
148
		$this->assertFileExists(
149
			AssetStoreTest_SpyStore::getLocalPath($file1)
150
		);
151
		$this->assertEquals(
152
			$file1->Filename,
153
			'FileTest-folder1-changed/File1.txt',
154
			'The file DataObject path uses renamed folder'
155
		);
156
157
		// File should be located in new folder
158
		$this->assertEquals(
159
			ASSETS_PATH . '/FolderTest/.protected/FileTest-folder1-changed/55b443b601/File1.txt',
160
			AssetStoreTest_SpyStore::getLocalPath($file1)
161
		);
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
173
	public function testIllegalFilenames() {
174
175
		// Test that generating a filename with invalid characters generates a correctly named folder.
176
		$folder = Folder::find_or_make('/FolderTest/EN_US Lang');
177
		$this->assertEquals('FolderTest/EN-US-Lang/', $folder->getFilename());
178
179
		// Test repeatitions of folder
180
		$folder2 = Folder::find_or_make('/FolderTest/EN_US Lang');
181
		$this->assertEquals($folder->ID, $folder2->ID);
182
183
		$folder3 = Folder::find_or_make('/FolderTest/EN--US_L!ang');
184
		$this->assertEquals($folder->ID, $folder3->ID);
185
186
		$folder4 = Folder::find_or_make('/FolderTest/EN-US-Lang');
187
		$this->assertEquals($folder->ID, $folder4->ID);
188
	}
189
190
	public function testTitleTiedToName() {
191
		$newFolder = new Folder();
192
193
		$newFolder->Name = 'TestNameCopiedToTitle';
194
		$this->assertEquals($newFolder->Name, $newFolder->Title);
195
196
		$newFolder->Title = 'TestTitleCopiedToName';
197
		$this->assertEquals($newFolder->Name, $newFolder->Title);
198
199
		$newFolder->Name = 'TestNameWithIllegalCharactersCopiedToTitle <!BANG!>';
200
		$this->assertEquals($newFolder->Name, $newFolder->Title);
201
202
		$newFolder->Title = 'TestTitleWithIllegalCharactersCopiedToName <!BANG!>';
203
		$this->assertEquals($newFolder->Name, $newFolder->Title);
204
	}
205
}
206