1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
use Filesystem as SS_Filesystem; |
4
|
|
|
use SilverStripe\Filesystem\Storage\AssetStore; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Tests for the File class |
8
|
|
|
*/ |
9
|
|
|
class FileTest extends SapphireTest { |
10
|
|
|
|
11
|
|
|
protected static $fixture_file = 'FileTest.yml'; |
12
|
|
|
|
13
|
|
|
protected $extraDataObjects = array('FileTest_MyCustomFile'); |
14
|
|
|
|
15
|
|
|
public function setUp() { |
16
|
|
|
parent::setUp(); |
17
|
|
|
$this->logInWithPermission('ADMIN'); |
18
|
|
|
Versioned::reading_stage('Stage'); |
19
|
|
|
|
20
|
|
|
// Set backend root to /ImageTest |
21
|
|
|
AssetStoreTest_SpyStore::activate('FileTest'); |
22
|
|
|
|
23
|
|
|
// Create a test folders for each of the fixture references |
24
|
|
|
$folderIDs = $this->allFixtureIDs('Folder'); |
25
|
|
|
foreach($folderIDs as $folderID) { |
|
|
|
|
26
|
|
|
$folder = DataObject::get_by_id('Folder', $folderID); |
27
|
|
|
$filePath = ASSETS_PATH . '/FileTest/' . $folder->getFilename(); |
28
|
|
|
SS_Filesystem::makeFolder($filePath); |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
// Create a test files for each of the fixture references |
32
|
|
|
$fileIDs = $this->allFixtureIDs('File'); |
33
|
|
|
foreach($fileIDs as $fileID) { |
|
|
|
|
34
|
|
|
$file = DataObject::get_by_id('File', $fileID); |
35
|
|
|
$root = ASSETS_PATH . '/FileTest/'; |
36
|
|
|
if($folder = $file->Parent()) { |
|
|
|
|
37
|
|
|
$root .= $folder->getFilename(); |
38
|
|
|
} |
39
|
|
|
$path = $root . substr($file->getHash(), 0, 10) . '/' . basename($file->getFilename()); |
40
|
|
|
SS_Filesystem::makeFolder(dirname($path)); |
41
|
|
|
$fh = fopen($path, "w+"); |
42
|
|
|
fwrite($fh, str_repeat('x', 1000000)); |
43
|
|
|
fclose($fh); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
// Conditional fixture creation in case the 'cms' module is installed |
47
|
|
|
if(class_exists('ErrorPage')) { |
48
|
|
|
$page = new ErrorPage(array( |
49
|
|
|
'Title' => 'Page not Found', |
50
|
|
|
'ErrorCode' => 404 |
51
|
|
|
)); |
52
|
|
|
$page->write(); |
53
|
|
|
$page->publish('Stage', 'Live'); |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
public function tearDown() { |
58
|
|
|
AssetStoreTest_SpyStore::reset(); |
59
|
|
|
parent::tearDown(); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
public function testLinkShortcodeHandler() { |
63
|
|
|
$testFile = $this->objFromFixture('File', 'asdf'); |
64
|
|
|
|
65
|
|
|
$parser = new ShortcodeParser(); |
66
|
|
|
$parser->register('file_link', array('File', 'handle_shortcode')); |
67
|
|
|
|
68
|
|
|
$fileShortcode = sprintf('[file_link,id=%d]', $testFile->ID); |
69
|
|
|
$fileEnclosed = sprintf('[file_link,id=%d]Example Content[/file_link]', $testFile->ID); |
70
|
|
|
|
71
|
|
|
$fileShortcodeExpected = $testFile->Link(); |
72
|
|
|
$fileEnclosedExpected = sprintf( |
73
|
|
|
'<a href="%s" class="file" data-type="txt" data-size="977 KB">Example Content</a>', $testFile->Link()); |
74
|
|
|
|
75
|
|
|
$this->assertEquals($fileShortcodeExpected, $parser->parse($fileShortcode), 'Test that simple linking works.'); |
76
|
|
|
$this->assertEquals($fileEnclosedExpected, $parser->parse($fileEnclosed), 'Test enclosed content is linked.'); |
77
|
|
|
|
78
|
|
|
$testFile->delete(); |
79
|
|
|
|
80
|
|
|
$fileShortcode = '[file_link,id="-1"]'; |
81
|
|
|
$fileEnclosed = '[file_link,id="-1"]Example Content[/file_link]'; |
82
|
|
|
|
83
|
|
|
$this->assertEquals('', $parser->parse('[file_link]'), 'Test that invalid ID attributes are not parsed.'); |
84
|
|
|
$this->assertEquals('', $parser->parse('[file_link,id="text"]')); |
85
|
|
|
$this->assertEquals('', $parser->parse('[file_link]Example Content[/file_link]')); |
86
|
|
|
|
87
|
|
|
if(class_exists('ErrorPage')) { |
88
|
|
|
$errorPage = ErrorPage::get()->filter('ErrorCode', 404)->First(); |
89
|
|
|
$this->assertEquals( |
90
|
|
|
$errorPage->Link(), |
91
|
|
|
$parser->parse($fileShortcode), |
92
|
|
|
'Test link to 404 page if no suitable matches.' |
93
|
|
|
); |
94
|
|
|
$this->assertEquals( |
95
|
|
|
sprintf('<a href="%s">Example Content</a>', $errorPage->Link()), |
96
|
|
|
$parser->parse($fileEnclosed) |
97
|
|
|
); |
98
|
|
|
} else { |
99
|
|
|
$this->assertEquals('', $parser->parse($fileShortcode), |
100
|
|
|
'Short code is removed if file record is not present.'); |
101
|
|
|
$this->assertEquals('', $parser->parse($fileEnclosed)); |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
public function testCreateWithFilenameWithSubfolder() { |
106
|
|
|
// Note: We can't use fixtures/setUp() for this, as we want to create the db record manually. |
107
|
|
|
// Creating the folder is necessary to avoid having "Filename" overwritten by setName()/setRelativePath(), |
108
|
|
|
// because the parent folders don't exist in the database |
109
|
|
|
$folder = Folder::find_or_make('/FileTest/'); |
110
|
|
|
$testfilePath = BASE_PATH . '/assets/FileTest/CreateWithFilenameHasCorrectPath.txt'; // Important: No leading slash |
111
|
|
|
$fh = fopen($testfilePath, "w"); |
112
|
|
|
fwrite($fh, str_repeat('x',1000000)); |
113
|
|
|
fclose($fh); |
114
|
|
|
|
115
|
|
|
$file = new File(); |
116
|
|
|
$file->setFromLocalFile($testfilePath); |
117
|
|
|
$file->ParentID = $folder->ID; |
118
|
|
|
$file->write(); |
119
|
|
|
|
120
|
|
|
$this->assertEquals( |
121
|
|
|
'CreateWithFilenameHasCorrectPath.txt', |
122
|
|
|
$file->Name, |
123
|
|
|
'"Name" property is automatically set from "Filename"' |
124
|
|
|
); |
125
|
|
|
$this->assertEquals( |
126
|
|
|
'FileTest/CreateWithFilenameHasCorrectPath.txt', |
127
|
|
|
$file->Filename, |
128
|
|
|
'"Filename" property remains unchanged' |
129
|
|
|
); |
130
|
|
|
|
131
|
|
|
// TODO This should be auto-detected, see File->updateFilesystem() |
132
|
|
|
// $this->assertInstanceOf('Folder', $file->Parent(), 'Parent folder is created in database'); |
|
|
|
|
133
|
|
|
// $this->assertFileExists($file->Parent()->getURL(), 'Parent folder is created on filesystem'); |
|
|
|
|
134
|
|
|
// $this->assertEquals('FileTest', $file->Parent()->Name); |
|
|
|
|
135
|
|
|
// $this->assertInstanceOf('Folder', $file->Parent()->Parent(), 'Grandparent folder is created in database'); |
|
|
|
|
136
|
|
|
// $this->assertFileExists($file->Parent()->Parent()->getURL(), |
|
|
|
|
137
|
|
|
// 'Grandparent folder is created on filesystem'); |
138
|
|
|
// $this->assertEquals('assets', $file->Parent()->Parent()->Name); |
|
|
|
|
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
public function testGetExtension() { |
142
|
|
|
$this->assertEquals('', File::get_file_extension('myfile'), |
143
|
|
|
'No extension'); |
144
|
|
|
$this->assertEquals('txt', File::get_file_extension('myfile.txt'), |
145
|
|
|
'Simple extension'); |
146
|
|
|
$this->assertEquals('gz', File::get_file_extension('myfile.tar.gz'), |
147
|
|
|
'Double-barrelled extension only returns last bit'); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function testValidateExtension() { |
151
|
|
|
Session::set('loggedInAs', null); |
152
|
|
|
|
153
|
|
|
$orig = Config::inst()->get('File', 'allowed_extensions'); |
154
|
|
|
Config::inst()->remove('File', 'allowed_extensions'); |
155
|
|
|
Config::inst()->update('File', 'allowed_extensions', array('txt')); |
156
|
|
|
|
157
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
158
|
|
|
|
159
|
|
|
// Invalid ext |
160
|
|
|
$file->Name = 'asdf.php'; |
|
|
|
|
161
|
|
|
$v = $file->validate(); |
162
|
|
|
$this->assertFalse($v->valid()); |
163
|
|
|
$this->assertContains('Extension is not allowed', $v->message()); |
164
|
|
|
|
165
|
|
|
// Valid ext |
166
|
|
|
$file->Name = 'asdf.txt'; |
|
|
|
|
167
|
|
|
$v = $file->validate(); |
168
|
|
|
$this->assertTrue($v->valid()); |
169
|
|
|
|
170
|
|
|
// Capital extension is valid as well |
171
|
|
|
$file->Name = 'asdf.TXT'; |
|
|
|
|
172
|
|
|
$v = $file->validate(); |
173
|
|
|
$this->assertTrue($v->valid()); |
174
|
|
|
|
175
|
|
|
Config::inst()->remove('File', 'allowed_extensions'); |
176
|
|
|
Config::inst()->update('File', 'allowed_extensions', $orig); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
public function testAppCategory() { |
180
|
|
|
// Test various categories |
181
|
|
|
$this->assertEquals('image', File::get_app_category('jpg')); |
182
|
|
|
$this->assertEquals('image', File::get_app_category('JPG')); |
183
|
|
|
$this->assertEquals('image', File::get_app_category('JPEG')); |
184
|
|
|
$this->assertEquals('image', File::get_app_category('png')); |
185
|
|
|
$this->assertEquals('image', File::get_app_category('tif')); |
186
|
|
|
$this->assertEquals('document', File::get_app_category('pdf')); |
187
|
|
|
$this->assertEquals('video', File::get_app_category('mov')); |
188
|
|
|
$this->assertEquals('audio', File::get_app_category('OGG')); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
public function testGetCategoryExtensions() { |
192
|
|
|
// Test specific categories |
193
|
|
|
$images = array( |
194
|
|
|
'alpha', 'als', 'bmp', 'cel', 'gif', 'ico', 'icon', 'jpeg', 'jpg', 'pcx', 'png', 'ps', 'tif', 'tiff' |
195
|
|
|
); |
196
|
|
|
$this->assertEquals($images, File::get_category_extensions('image')); |
197
|
|
|
$this->assertEquals(array('gif', 'jpeg', 'jpg', 'png'), File::get_category_extensions('image/supported')); |
198
|
|
|
$this->assertEquals($images, File::get_category_extensions(array('image', 'image/supported'))); |
199
|
|
|
$this->assertEquals( |
200
|
|
|
array('fla', 'gif', 'jpeg', 'jpg', 'png', 'swf'), |
201
|
|
|
File::get_category_extensions(array('flash', 'image/supported')) |
202
|
|
|
); |
203
|
|
|
|
204
|
|
|
// Test other categories have at least one item |
205
|
|
|
$this->assertNotEmpty(File::get_category_extensions('archive')); |
206
|
|
|
$this->assertNotEmpty(File::get_category_extensions('audio')); |
207
|
|
|
$this->assertNotEmpty(File::get_category_extensions('document')); |
208
|
|
|
$this->assertNotEmpty(File::get_category_extensions('flash')); |
209
|
|
|
$this->assertNotEmpty(File::get_category_extensions('video')); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @dataProvider allowedExtensions |
214
|
|
|
* @param string $extension |
215
|
|
|
*/ |
216
|
|
|
public function testAllFilesHaveCategory($extension) { |
217
|
|
|
$this->assertNotEmpty( |
218
|
|
|
File::get_app_category($extension), |
219
|
|
|
"Assert that extension {$extension} has a valid category" |
220
|
|
|
); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Gets the list of all extensions for testing |
225
|
|
|
* |
226
|
|
|
* @return array |
227
|
|
|
*/ |
228
|
|
|
public function allowedExtensions() { |
229
|
|
|
$args = array(); |
230
|
|
|
foreach(array_filter(File::config()->allowed_extensions) as $ext) { |
231
|
|
|
$args[] = array($ext); |
232
|
|
|
} |
233
|
|
|
return $args; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
public function testSetNameChangesFilesystemOnWrite() { |
237
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
238
|
|
|
$this->logInWithPermission('ADMIN'); |
239
|
|
|
$file->doPublish(); |
240
|
|
|
$oldTuple = $file->File->getValue(); |
241
|
|
|
|
242
|
|
|
// Rename |
243
|
|
|
$file->Name = 'renamed.txt'; |
|
|
|
|
244
|
|
|
$newTuple = $oldTuple; |
245
|
|
|
$newTuple['Filename'] = $file->getFilename(); |
246
|
|
|
|
247
|
|
|
// Before write() |
248
|
|
|
$this->assertTrue( |
249
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
250
|
|
|
'Old path is still present' |
251
|
|
|
); |
252
|
|
|
$this->assertFalse( |
253
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
254
|
|
|
'New path is updated in memory, not written before write() is called' |
255
|
|
|
); |
256
|
|
|
|
257
|
|
|
// After write() |
258
|
|
|
$file->write(); |
259
|
|
|
$this->assertTrue( |
260
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
261
|
|
|
'Old path exists after draft change' |
262
|
|
|
); |
263
|
|
|
$this->assertTrue( |
264
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
265
|
|
|
'New path is created after write()' |
266
|
|
|
); |
267
|
|
|
|
268
|
|
|
// After publish |
269
|
|
|
$file->doPublish(); |
270
|
|
|
$this->assertFalse( |
271
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
272
|
|
|
'Old file is finally removed after publishing new file' |
273
|
|
|
); |
274
|
|
|
$this->assertTrue( |
275
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
276
|
|
|
'New path is created after write()' |
277
|
|
|
); |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
public function testSetParentIDChangesFilesystemOnWrite() { |
281
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
282
|
|
|
$this->logInWithPermission('ADMIN'); |
283
|
|
|
$file->doPublish(); |
284
|
|
|
$subfolder = $this->objFromFixture('Folder', 'subfolder'); |
285
|
|
|
$oldTuple = $file->File->getValue(); |
286
|
|
|
|
287
|
|
|
// set ParentID |
288
|
|
|
$file->ParentID = $subfolder->ID; |
|
|
|
|
289
|
|
|
$newTuple = $oldTuple; |
290
|
|
|
$newTuple['Filename'] = $file->getFilename(); |
291
|
|
|
|
292
|
|
|
// Before write() |
293
|
|
|
$this->assertTrue( |
294
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
295
|
|
|
'Old path is still present' |
296
|
|
|
); |
297
|
|
|
$this->assertFalse( |
298
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
299
|
|
|
'New path is updated in memory, not written before write() is called' |
300
|
|
|
); |
301
|
|
|
$file->write(); |
302
|
|
|
|
303
|
|
|
// After write() |
304
|
|
|
$file->write(); |
305
|
|
|
$this->assertTrue( |
306
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
307
|
|
|
'Old path exists after draft change' |
308
|
|
|
); |
309
|
|
|
$this->assertTrue( |
310
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
311
|
|
|
'New path is created after write()' |
312
|
|
|
); |
313
|
|
|
|
314
|
|
|
// After publish |
315
|
|
|
$file->doPublish(); |
316
|
|
|
$this->assertFalse( |
317
|
|
|
$this->getAssetStore()->exists($oldTuple['Filename'], $oldTuple['Hash']), |
318
|
|
|
'Old file is finally removed after publishing new file' |
319
|
|
|
); |
320
|
|
|
$this->assertTrue( |
321
|
|
|
$this->getAssetStore()->exists($newTuple['Filename'], $newTuple['Hash']), |
322
|
|
|
'New path is created after write()' |
323
|
|
|
); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @see http://open.silverstripe.org/ticket/5693 |
328
|
|
|
* |
329
|
|
|
* @expectedException ValidationException |
330
|
|
|
*/ |
331
|
|
|
public function testSetNameWithInvalidExtensionDoesntChangeFilesystem() { |
332
|
|
|
$orig = Config::inst()->get('File', 'allowed_extensions'); |
333
|
|
|
Config::inst()->remove('File', 'allowed_extensions'); |
334
|
|
|
Config::inst()->update('File', 'allowed_extensions', array('txt')); |
335
|
|
|
|
336
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
337
|
|
|
$oldPath = $file->getURL(); |
338
|
|
|
|
339
|
|
|
$file->Name = 'renamed.php'; // evil extension |
|
|
|
|
340
|
|
|
try { |
341
|
|
|
$file->write(); |
342
|
|
|
} catch(ValidationException $e) { |
343
|
|
|
Config::inst()->remove('File', 'allowed_extensions'); |
344
|
|
|
Config::inst()->update('File', 'allowed_extensions', $orig); |
345
|
|
|
throw $e; |
346
|
|
|
} |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
public function testGetURL() { |
350
|
|
|
$rootfile = $this->objFromFixture('File', 'asdf'); |
351
|
|
|
$this->assertEquals('/assets/FileTest/55b443b601/FileTest.txt', $rootfile->getURL()); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
public function testGetAbsoluteURL() { |
355
|
|
|
$rootfile = $this->objFromFixture('File', 'asdf'); |
356
|
|
|
$this->assertEquals( |
357
|
|
|
Director::absoluteBaseURL() . 'assets/FileTest/55b443b601/FileTest.txt', |
358
|
|
|
$rootfile->getAbsoluteURL() |
359
|
|
|
); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
public function testNameAndTitleGeneration() { |
363
|
|
|
// When name is assigned, title is automatically assigned |
364
|
|
|
$file = $this->objFromFixture('Image', 'setfromname'); |
365
|
|
|
$this->assertEquals('FileTest', $file->Title); |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
public function testSizeAndAbsoluteSizeParameters() { |
369
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
370
|
|
|
|
371
|
|
|
/* AbsoluteSize will give the integer number */ |
372
|
|
|
$this->assertEquals(1000000, $file->AbsoluteSize); |
373
|
|
|
/* Size will give a humanised number */ |
374
|
|
|
$this->assertEquals('977 KB', $file->Size); |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
public function testFileType() { |
378
|
|
|
$file = $this->objFromFixture('Image', 'gif'); |
379
|
|
|
$this->assertEquals("GIF image - good for diagrams", $file->FileType); |
380
|
|
|
|
381
|
|
|
$file = $this->objFromFixture('File', 'pdf'); |
382
|
|
|
$this->assertEquals("Adobe Acrobat PDF file", $file->FileType); |
383
|
|
|
|
384
|
|
|
$file = $this->objFromFixture('Image', 'gifupper'); |
385
|
|
|
$this->assertEquals("GIF image - good for diagrams", $file->FileType); |
386
|
|
|
|
387
|
|
|
/* Only a few file types are given special descriptions; the rest are unknown */ |
388
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
389
|
|
|
$this->assertEquals("unknown", $file->FileType); |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* Test the File::format_size() method |
394
|
|
|
*/ |
395
|
|
|
public function testFormatSize() { |
396
|
|
|
$this->assertEquals("1000 bytes", File::format_size(1000)); |
397
|
|
|
$this->assertEquals("1023 bytes", File::format_size(1023)); |
398
|
|
|
$this->assertEquals("1 KB", File::format_size(1025)); |
399
|
|
|
$this->assertEquals("9.8 KB", File::format_size(10000)); |
400
|
|
|
$this->assertEquals("49 KB", File::format_size(50000)); |
401
|
|
|
$this->assertEquals("977 KB", File::format_size(1000000)); |
402
|
|
|
$this->assertEquals("1 MB", File::format_size(1024*1024)); |
403
|
|
|
$this->assertEquals("954 MB", File::format_size(1000000000)); |
404
|
|
|
$this->assertEquals("1 GB", File::format_size(1024*1024*1024)); |
405
|
|
|
$this->assertEquals("9.3 GB", File::format_size(10000000000)); |
406
|
|
|
// It use any denomination higher than GB. It also doesn't overflow with >32 bit integers |
407
|
|
|
$this->assertEquals("93132.3 GB", File::format_size(100000000000000)); |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
public function testDeleteFile() { |
411
|
|
|
$file = $this->objFromFixture('File', 'asdf'); |
412
|
|
|
$this->logInWithPermission('ADMIN'); |
413
|
|
|
$file->doPublish(); |
414
|
|
|
$tuple = $file->File->getValue(); |
415
|
|
|
|
416
|
|
|
// Before delete |
417
|
|
|
$this->assertTrue( |
418
|
|
|
$this->getAssetStore()->exists($tuple['Filename'], $tuple['Hash']), |
419
|
|
|
'File is still present' |
420
|
|
|
); |
421
|
|
|
|
422
|
|
|
// after unpublish |
423
|
|
|
$file->doUnpublish(); |
424
|
|
|
$this->assertTrue( |
425
|
|
|
$this->getAssetStore()->exists($tuple['Filename'], $tuple['Hash']), |
426
|
|
|
'File is still present after unpublish' |
427
|
|
|
); |
428
|
|
|
|
429
|
|
|
// after delete |
430
|
|
|
$file->delete(); |
431
|
|
|
$this->assertFalse( |
432
|
|
|
$this->getAssetStore()->exists($tuple['Filename'], $tuple['Hash']), |
433
|
|
|
'File is deleted after unpublish and delete' |
434
|
|
|
); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
public function testRenameFolder() { |
438
|
|
|
$newTitle = "FileTest-folder-renamed"; |
439
|
|
|
|
440
|
|
|
//rename a folder's title |
441
|
|
|
$folderID = $this->objFromFixture("Folder","folder2")->ID; |
442
|
|
|
$folder = DataObject::get_by_id('Folder',$folderID); |
443
|
|
|
$folder->Title = $newTitle; |
|
|
|
|
444
|
|
|
$folder->write(); |
445
|
|
|
|
446
|
|
|
//get folder again and see if the filename has changed |
447
|
|
|
$folder = DataObject::get_by_id('Folder',$folderID); |
448
|
|
|
$this->assertEquals( |
449
|
|
|
$newTitle . "/", |
450
|
|
|
$folder->Filename, |
451
|
|
|
"Folder Filename updated after rename of Title" |
452
|
|
|
); |
453
|
|
|
|
454
|
|
|
//rename a folder's name |
455
|
|
|
$newTitle2 = "FileTest-folder-renamed2"; |
456
|
|
|
$folder->Name = $newTitle2; |
|
|
|
|
457
|
|
|
$folder->write(); |
458
|
|
|
|
459
|
|
|
//get folder again and see if the Title has changed |
460
|
|
|
$folder = DataObject::get_by_id('Folder',$folderID); |
461
|
|
|
$this->assertEquals($folder->Title, $newTitle2, |
462
|
|
|
"Folder Title updated after rename of Name"); |
463
|
|
|
|
464
|
|
|
|
465
|
|
|
//rename a folder's Filename |
466
|
|
|
$newTitle3 = "FileTest-folder-renamed3"; |
467
|
|
|
$folder->Filename = $newTitle3; |
|
|
|
|
468
|
|
|
$folder->write(); |
469
|
|
|
|
470
|
|
|
//get folder again and see if the Title has changed |
471
|
|
|
$folder = DataObject::get_by_id('Folder',$folderID); |
472
|
|
|
$this->assertEquals($folder->Title, $newTitle3, |
473
|
|
|
"Folder Title updated after rename of Filename"); |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
public function testSetsOwnerOnFirstWrite() { |
477
|
|
|
Session::set('loggedInAs', null); |
478
|
|
|
$member1 = new Member(); |
479
|
|
|
$member1->write(); |
480
|
|
|
$member2 = new Member(); |
481
|
|
|
$member2->write(); |
482
|
|
|
|
483
|
|
|
$file1 = new File(); |
484
|
|
|
$file1->write(); |
485
|
|
|
$this->assertEquals(0, $file1->OwnerID, 'Owner not written when no user is logged in'); |
486
|
|
|
|
487
|
|
|
$member1->logIn(); |
488
|
|
|
$file2 = new File(); |
489
|
|
|
$file2->write(); |
490
|
|
|
$this->assertEquals($member1->ID, $file2->OwnerID, 'Owner written when user is logged in'); |
491
|
|
|
|
492
|
|
|
$member2->logIn(); |
493
|
|
|
$file2->forceChange(); |
494
|
|
|
$file2->write(); |
495
|
|
|
$this->assertEquals($member1->ID, $file2->OwnerID, 'Owner not overwritten on existing files'); |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
public function testCanEdit() { |
499
|
|
|
$file = $this->objFromFixture('Image', 'gif'); |
500
|
|
|
|
501
|
|
|
// Test anonymous permissions |
502
|
|
|
Session::set('loggedInAs', null); |
503
|
|
|
$this->assertFalse($file->canEdit(), "Anonymous users can't edit files"); |
504
|
|
|
|
505
|
|
|
// Test permissionless user |
506
|
|
|
$this->objFromFixture('Member', 'frontend')->logIn(); |
507
|
|
|
$this->assertFalse($file->canEdit(), "Permissionless users can't edit files"); |
508
|
|
|
|
509
|
|
|
// Test global CMS section users |
510
|
|
|
$this->objFromFixture('Member', 'cms')->logIn(); |
511
|
|
|
$this->assertTrue($file->canEdit(), "Users with all CMS section access can edit files"); |
512
|
|
|
|
513
|
|
|
// Test cms access users without file access |
514
|
|
|
$this->objFromFixture('Member', 'security')->logIn(); |
515
|
|
|
$this->assertFalse($file->canEdit(), "Security CMS users can't edit files"); |
516
|
|
|
|
517
|
|
|
// Test asset-admin user |
518
|
|
|
$this->objFromFixture('Member', 'assetadmin')->logIn(); |
519
|
|
|
$this->assertTrue($file->canEdit(), "Asset admin users can edit files"); |
520
|
|
|
|
521
|
|
|
// Test admin |
522
|
|
|
$this->objFromFixture('Member', 'admin')->logIn(); |
523
|
|
|
$this->assertTrue($file->canEdit(), "Admins can edit files"); |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
|
527
|
|
|
public function testJoinPaths() { |
528
|
|
|
$this->assertEquals('name/file.jpg', File::join_paths('/name', 'file.jpg')); |
529
|
|
|
$this->assertEquals('name/file.jpg', File::join_paths('name', 'file.jpg')); |
530
|
|
|
$this->assertEquals('name/file.jpg', File::join_paths('/name', '/file.jpg')); |
531
|
|
|
$this->assertEquals('name/file.jpg', File::join_paths('name/', '/', 'file.jpg')); |
532
|
|
|
$this->assertEquals('file.jpg', File::join_paths('/', '/', 'file.jpg')); |
533
|
|
|
$this->assertEquals('', File::join_paths('/', '/')); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
/** |
537
|
|
|
* @return AssetStore |
538
|
|
|
*/ |
539
|
|
|
protected function getAssetStore() { |
540
|
|
|
return Injector::inst()->get('AssetStore'); |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
class FileTest_MyCustomFile extends File implements TestOnly { |
546
|
|
|
|
547
|
|
|
} |
548
|
|
|
|