MDL-39087 Delete all component files in uninstall_plugin()
[moodle.git] / lib / filestorage / tests / file_storage_test.php
CommitLineData
8f110835
DM
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Unit tests for /lib/filestorage/file_storage.php
20 *
21 * @package core
22 * @category test
23 * @copyright 2012 David Mudrak <david@moodle.com>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29global $CFG;
30require_once($CFG->libdir . '/filelib.php');
ac29403e 31require_once($CFG->dirroot . '/repository/lib.php');
8f110835
DM
32
33class filestoragelib_testcase extends advanced_testcase {
34
35 /**
36 * Local files can be added to the filepool
37 */
38 public function test_create_file_from_pathname() {
39 global $CFG;
40
41 $this->resetAfterTest(false);
42
43 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
44 $syscontext = context_system::instance();
45 $filerecord = array(
46 'contextid' => $syscontext->id,
47 'component' => 'core',
48 'filearea' => 'unittest',
49 'itemid' => 0,
50 'filepath' => '/images/',
51 'filename' => 'testimage.jpg',
52 );
53
54 $fs = get_file_storage();
55 $fs->create_file_from_pathname($filerecord, $filepath);
56
57 $this->assertTrue($fs->file_exists($syscontext->id, 'core', 'unittest', 0, '/images/', 'testimage.jpg'));
58
59 return $fs->get_file($syscontext->id, 'core', 'unittest', 0, '/images/', 'testimage.jpg');
60 }
61
62 /**
63 * Local images can be added to the filepool and their preview can be obtained
64 *
65 * @depends test_create_file_from_pathname
66 */
67 public function test_get_file_preview(stored_file $file) {
68 global $CFG;
69
70 $this->resetAfterTest(true);
71 $fs = get_file_storage();
72
73 $previewtinyicon = $fs->get_file_preview($file, 'tinyicon');
74 $this->assertInstanceOf('stored_file', $previewtinyicon);
75 $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename());
76
77 $previewtinyicon = $fs->get_file_preview($file, 'thumb');
78 $this->assertInstanceOf('stored_file', $previewtinyicon);
79 $this->assertEquals('6b9864ae1536a8eeef54e097319175a8be12f07c', $previewtinyicon->get_filename());
7c89a18f
DP
80
81 $this->setExpectedException('file_exception');
82 $fs->get_file_preview($file, 'amodewhichdoesntexist');
83 }
84
85 public function test_get_file_preview_nonimage() {
86 $this->resetAfterTest(true);
87 $syscontext = context_system::instance();
88 $filerecord = array(
89 'contextid' => $syscontext->id,
90 'component' => 'core',
91 'filearea' => 'unittest',
92 'itemid' => 0,
93 'filepath' => '/textfiles/',
94 'filename' => 'testtext.txt',
95 );
96
97 $fs = get_file_storage();
98 $fs->create_file_from_string($filerecord, 'text contents');
99 $textfile = $fs->get_file($syscontext->id, $filerecord['component'], $filerecord['filearea'],
100 $filerecord['itemid'], $filerecord['filepath'], $filerecord['filename']);
101
102 $preview = $fs->get_file_preview($textfile, 'thumb');
103 $this->assertFalse($preview);
8f110835 104 }
67233725
DC
105
106 /**
107 * Make sure renaming is working
108 *
109 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
110 */
111 public function test_file_renaming() {
112 global $CFG;
113
114 $this->resetAfterTest(true);
115 $fs = get_file_storage();
116 $syscontext = context_system::instance();
117 $component = 'core';
118 $filearea = 'unittest';
119 $itemid = 0;
120 $filepath = '/';
121 $filename = 'test.txt';
122
123 $filerecord = array(
124 'contextid' => $syscontext->id,
125 'component' => $component,
126 'filearea' => $filearea,
127 'itemid' => $itemid,
128 'filepath' => $filepath,
129 'filename' => $filename,
130 );
131
132 $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
133 $this->assertInstanceOf('stored_file', $originalfile);
134 $contenthash = $originalfile->get_contenthash();
135 $newpath = '/test/';
136 $newname = 'newtest.txt';
61506a0a 137
7051415c 138 // this should work
67233725 139 $originalfile->rename($newpath, $newname);
67233725
DC
140 $file = $fs->get_file($syscontext->id, $component, $filearea, $itemid, $newpath, $newname);
141 $this->assertInstanceOf('stored_file', $file);
142 $this->assertEquals($contenthash, $file->get_contenthash());
61506a0a
DC
143
144 // try break it
145 $this->setExpectedException('file_exception');
146 // this shall throw exception
147 $originalfile->rename($newpath, $newname);
67233725
DC
148 }
149
150 /**
151 * Create file from reference tests
152 *
153 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
154 */
155 public function test_create_file_from_reference() {
156 global $CFG, $DB;
157
158 $this->resetAfterTest(true);
159 // create user
160 $generator = $this->getDataGenerator();
161 $user = $generator->create_user();
cfc4db40 162 $this->setUser($user);
67233725
DC
163 $usercontext = context_user::instance($user->id);
164 $syscontext = context_system::instance();
67233725
DC
165
166 $fs = get_file_storage();
167
168 $repositorypluginname = 'user';
169 // override repository permission
170 $capability = 'repository/' . $repositorypluginname . ':view';
171 $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id');
172 assign_capability($capability, CAP_ALLOW, $allroles['guest'], $syscontext->id, true);
173
174
175 $args = array();
176 $args['type'] = $repositorypluginname;
177 $repos = repository::get_instances($args);
178 $userrepository = reset($repos);
179 $this->assertInstanceOf('repository', $userrepository);
180
181 $component = 'user';
182 $filearea = 'private';
183 $itemid = 0;
184 $filepath = '/';
185 $filename = 'userfile.txt';
186
187 $filerecord = array(
188 'contextid' => $usercontext->id,
189 'component' => $component,
190 'filearea' => $filearea,
191 'itemid' => $itemid,
192 'filepath' => $filepath,
193 'filename' => $filename,
194 );
195
196 $content = 'Test content';
197 $originalfile = $fs->create_file_from_string($filerecord, $content);
198 $this->assertInstanceOf('stored_file', $originalfile);
199
200 $newfilerecord = array(
201 'contextid' => $syscontext->id,
202 'component' => 'core',
203 'filearea' => 'phpunit',
204 'itemid' => 0,
205 'filepath' => $filepath,
206 'filename' => $filename,
207 );
208 $ref = $fs->pack_reference($filerecord);
209 $newstoredfile = $fs->create_file_from_reference($newfilerecord, $userrepository->id, $ref);
210 $this->assertInstanceOf('stored_file', $newstoredfile);
291a3d1f 211 $this->assertEquals($userrepository->id, $newstoredfile->get_repository_id());
67233725
DC
212 $this->assertEquals($originalfile->get_contenthash(), $newstoredfile->get_contenthash());
213 $this->assertEquals($originalfile->get_filesize(), $newstoredfile->get_filesize());
214 $this->assertRegExp('#' . $filename. '$#', $newstoredfile->get_reference_details());
215
216 // Test looking for references
217 $count = $fs->get_references_count_by_storedfile($originalfile);
218 $this->assertEquals(1, $count);
219 $files = $fs->get_references_by_storedfile($originalfile);
220 $file = reset($files);
221 $this->assertEquals($file, $newstoredfile);
222
223 // Look for references by repository ID
224 $files = $fs->get_external_files($userrepository->id);
225 $file = reset($files);
226 $this->assertEquals($file, $newstoredfile);
227
228 // Try convert reference to local file
229 $importedfile = $fs->import_external_file($newstoredfile);
230 $this->assertFalse($importedfile->is_external_file());
231 $this->assertInstanceOf('stored_file', $importedfile);
232 // still readable?
233 $this->assertEquals($content, $importedfile->get_content());
234 }
ac29403e 235
ac29403e 236 private function setup_three_private_files() {
ac29403e
DP
237
238 $this->resetAfterTest(true);
239
240 $generator = $this->getDataGenerator();
241 $user = $generator->create_user();
7c89a18f 242 $this->setUser($user->id);
ac29403e 243 $usercontext = context_user::instance($user->id);
ac29403e
DP
244 // create a user private file
245 $file1 = new stdClass;
246 $file1->contextid = $usercontext->id;
247 $file1->component = 'user';
248 $file1->filearea = 'private';
249 $file1->itemid = 0;
250 $file1->filepath = '/';
251 $file1->filename = '1.txt';
252 $file1->source = 'test';
253
254 $fs = get_file_storage();
255 $userfile1 = $fs->create_file_from_string($file1, 'file1 content');
7c89a18f
DP
256 $this->assertInstanceOf('stored_file', $userfile1);
257
ac29403e
DP
258 $file2 = clone($file1);
259 $file2->filename = '2.txt';
260 $userfile2 = $fs->create_file_from_string($file2, 'file2 content');
7c89a18f 261 $this->assertInstanceOf('stored_file', $userfile2);
ac29403e
DP
262
263 $file3 = clone($file1);
264 $file3->filename = '3.txt';
265 $userfile3 = $fs->create_file_from_storedfile($file3, $userfile2);
7c89a18f 266 $this->assertInstanceOf('stored_file', $userfile3);
ac29403e
DP
267
268 $user->ctxid = $usercontext->id;
269
270 return $user;
271 }
272
ac29403e
DP
273 public function test_get_area_files() {
274 $user = $this->setup_three_private_files();
275 $fs = get_file_storage();
276
277 // Get area files with default options.
278 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
7c89a18f 279
ac29403e
DP
280 // Should be the two files we added plus the folder.
281 $this->assertEquals(4, count($areafiles));
282
7c89a18f 283 // Verify structure.
294d976e 284 foreach ($areafiles as $key => $file) {
7c89a18f
DP
285 $this->assertInstanceOf('stored_file', $file);
286 $this->assertEquals($key, $file->get_pathnamehash());
287 }
288
ac29403e 289 // Get area files without a folder.
7c89a18f 290 $folderlessfiles = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'sortorder', false);
ac29403e 291 // Should be the two files without folder.
7c89a18f
DP
292 $this->assertEquals(3, count($folderlessfiles));
293
294 // Verify structure.
294d976e 295 foreach ($folderlessfiles as $key => $file) {
7c89a18f
DP
296 $this->assertInstanceOf('stored_file', $file);
297 $this->assertEquals($key, $file->get_pathnamehash());
298 }
ac29403e 299
d83ce953 300 // Get area files ordered by id.
7c89a18f 301 $filesbyid = $fs->get_area_files($user->ctxid, 'user', 'private', false, 'id', false);
ac29403e 302 // Should be the two files without folder.
7c89a18f
DP
303 $this->assertEquals(3, count($filesbyid));
304
305 // Verify structure.
294d976e 306 foreach ($filesbyid as $key => $file) {
7c89a18f
DP
307 $this->assertInstanceOf('stored_file', $file);
308 $this->assertEquals($key, $file->get_pathnamehash());
309 }
ac29403e
DP
310
311 // Test with an itemid with no files
312 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private', 666, 'sortorder', false);
294d976e 313 // Should be none.
7c89a18f 314 $this->assertEmpty($areafiles);
ac29403e
DP
315 }
316
317 public function test_get_area_tree() {
318 $user = $this->setup_three_private_files();
319 $fs = get_file_storage();
320
7c89a18f 321
ac29403e 322 // Get area files with default options.
7c89a18f
DP
323 $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0);
324 $this->assertEmpty($areatree['subdirs']);
325 $this->assertNotEmpty($areatree['files']);
326 $this->assertCount(3, $areatree['files']);
327
328 // Ensure an empty try with a fake itemid.
329 $emptytree = $fs->get_area_tree($user->ctxid, 'user', 'private', 666);
330 $this->assertEmpty($emptytree['subdirs']);
331 $this->assertEmpty($emptytree['files']);
332
294d976e 333 // Create a subdir.
7c89a18f
DP
334 $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/');
335 $this->assertInstanceOf('stored_file', $dir);
336
337 // Add a file to the subdir.
338 $filerecord = array(
339 'contextid' => $user->ctxid,
340 'component' => 'user',
341 'filearea' => 'private',
342 'itemid' => 0,
343 'filepath' => '/testsubdir/',
344 'filename' => 'test-get-area-tree.txt',
345 );
346
347 $directoryfile = $fs->create_file_from_string($filerecord, 'Test content');
348 $this->assertInstanceOf('stored_file', $directoryfile);
349
350 $areatree = $fs->get_area_tree($user->ctxid, 'user', 'private', 0);
351
352 // At the top level there should still be 3 files.
353 $this->assertCount(3, $areatree['files']);
354
355 // There should now be a subdirectory.
356 $this->assertCount(1, $areatree['subdirs']);
357
358 // The test subdir is named testsubdir.
359 $subdir = $areatree['subdirs']['testsubdir'];
360 $this->assertNotEmpty($subdir);
361 // It should have one file we added.
362 $this->assertCount(1, $subdir['files']);
363 // And no subdirs itself.
364 $this->assertCount(0, $subdir['subdirs']);
365
294d976e 366 // Verify the file is the one we added.
7c89a18f
DP
367 $subdirfile = reset($subdir['files']);
368 $this->assertInstanceOf('stored_file', $subdirfile);
369 $this->assertEquals($filerecord['filename'], $subdirfile->get_filename());
ac29403e
DP
370 }
371
372 public function test_get_file_by_id() {
373 $user = $this->setup_three_private_files();
374 $fs = get_file_storage();
375
376 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
377
378 // Test get_file_by_id.
379 $filebyid = reset($areafiles);
380 $shouldbesame = $fs->get_file_by_id($filebyid->get_id());
381 $this->assertEquals($filebyid->get_contenthash(), $shouldbesame->get_contenthash());
7c89a18f
DP
382
383 // Test an id which doens't exist.
384 $doesntexist = $fs->get_file_by_id(99999);
385 $this->assertFalse($doesntexist);
ac29403e
DP
386 }
387
388 public function test_get_file_by_hash() {
389 $user = $this->setup_three_private_files();
390 $fs = get_file_storage();
391
392 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
393 // Test get_file_by_hash
394 $filebyhash = reset($areafiles);
395 $shouldbesame = $fs->get_file_by_hash($filebyhash->get_pathnamehash());
396 $this->assertEquals($filebyhash->get_id(), $shouldbesame->get_id());
7c89a18f
DP
397
398 // Test an hash which doens't exist.
399 $doesntexist = $fs->get_file_by_hash('DOESNTEXIST');
400 $this->assertFalse($doesntexist);
ac29403e
DP
401 }
402
ac29403e
DP
403 public function test_get_external_files() {
404 $user = $this->setup_three_private_files();
405 $fs = get_file_storage();
406
407 $repos = repository::get_instances(array('type'=>'user'));
408 $userrepository = reset($repos);
409 $this->assertInstanceOf('repository', $userrepository);
410
d83ce953
DM
411 // no aliases yet
412 $exfiles = $fs->get_external_files($userrepository->id, 'id');
413 $this->assertEquals(array(), $exfiles);
414
415 // create three aliases linking the same original: $aliasfile1 and $aliasfile2 are
416 // created via create_file_from_reference(), $aliasfile3 created from $aliasfile2
417 $originalfile = null;
418 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
419 if (!$areafile->is_directory()) {
420 $originalfile = $areafile;
421 break;
422 }
423 }
424 $this->assertInstanceOf('stored_file', $originalfile);
425 $originalrecord = array(
426 'contextid' => $originalfile->get_contextid(),
427 'component' => $originalfile->get_component(),
428 'filearea' => $originalfile->get_filearea(),
429 'itemid' => $originalfile->get_itemid(),
430 'filepath' => $originalfile->get_filepath(),
431 'filename' => $originalfile->get_filename(),
432 );
433
434 $aliasrecord = $this->generate_file_record();
435 $aliasrecord->filepath = '/foo/';
436 $aliasrecord->filename = 'one.txt';
437
438 $ref = $fs->pack_reference($originalrecord);
439 $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref);
440
441 $aliasrecord->filepath = '/bar/';
442 $aliasrecord->filename = 'uno.txt';
443 // change the order of the items in the array to make sure that it does not matter
444 ksort($originalrecord);
445 $ref = $fs->pack_reference($originalrecord);
446 $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $userrepository->id, $ref);
447
448 $aliasrecord->filepath = '/bar/';
449 $aliasrecord->filename = 'jedna.txt';
450 $aliasfile3 = $fs->create_file_from_storedfile($aliasrecord, $aliasfile2);
451
452 // make sure we get three aliases now
453 $exfiles = $fs->get_external_files($userrepository->id, 'id');
454 $this->assertEquals(3, count($exfiles));
455 foreach ($exfiles as $exfile) {
456 $this->assertTrue($exfile->is_external_file());
457 }
458 // make sure they all link the same original (thence that all are linked with the same
459 // record in {files_reference})
460 $this->assertEquals($aliasfile1->get_referencefileid(), $aliasfile2->get_referencefileid());
461 $this->assertEquals($aliasfile3->get_referencefileid(), $aliasfile2->get_referencefileid());
7c89a18f
DP
462 }
463
464 public function test_create_directory_contextid_negative() {
465 $fs = get_file_storage();
466
467 $this->setExpectedException('file_exception');
468 $fs->create_directory(-1, 'core', 'unittest', 0, '/');
469 }
470
471 public function test_create_directory_contextid_invalid() {
472 $fs = get_file_storage();
473
474 $this->setExpectedException('file_exception');
475 $fs->create_directory('not an int', 'core', 'unittest', 0, '/');
476 }
477
478 public function test_create_directory_component_invalid() {
479 $fs = get_file_storage();
480 $syscontext = context_system::instance();
481
482 $this->setExpectedException('file_exception');
483 $fs->create_directory($syscontext->id, 'bad/component', 'unittest', 0, '/');
484 }
485
486 public function test_create_directory_filearea_invalid() {
487 $fs = get_file_storage();
488 $syscontext = context_system::instance();
489
490 $this->setExpectedException('file_exception');
491 $fs->create_directory($syscontext->id, 'core', 'bad-filearea', 0, '/');
492 }
493
494 public function test_create_directory_itemid_negative() {
495 $fs = get_file_storage();
496 $syscontext = context_system::instance();
497
498 $this->setExpectedException('file_exception');
499 $fs->create_directory($syscontext->id, 'core', 'unittest', -1, '/');
500 }
501
502 public function test_create_directory_itemid_invalid() {
503 $fs = get_file_storage();
504 $syscontext = context_system::instance();
505
506 $this->setExpectedException('file_exception');
507 $fs->create_directory($syscontext->id, 'core', 'unittest', 'notanint', '/');
508 }
509
510 public function test_create_directory_filepath_invalid() {
511 $fs = get_file_storage();
512 $syscontext = context_system::instance();
513
514 $this->setExpectedException('file_exception');
515 $fs->create_directory($syscontext->id, 'core', 'unittest', 0, '/not-with-trailing/or-leading-slash');
516 }
ac29403e
DP
517
518 public function test_get_directory_files() {
519 $user = $this->setup_three_private_files();
520 $fs = get_file_storage();
521
7c89a18f
DP
522 $dir = $fs->create_directory($user->ctxid, 'user', 'private', 0, '/testsubdir/');
523 $this->assertInstanceOf('stored_file', $dir);
ac29403e 524
7c89a18f
DP
525 // Add a file to the subdir.
526 $filerecord = array(
527 'contextid' => $user->ctxid,
528 'component' => 'user',
529 'filearea' => 'private',
530 'itemid' => 0,
531 'filepath' => '/testsubdir/',
532 'filename' => 'test-get-area-tree.txt',
533 );
534
535 $directoryfile = $fs->create_file_from_string($filerecord, 'Test content');
536 $this->assertInstanceOf('stored_file', $directoryfile);
ac29403e
DP
537
538 // Don't recurse without dirs
7c89a18f
DP
539 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, false, 'id');
540 // 3 files only.
541 $this->assertCount(3, $files);
294d976e 542 foreach ($files as $key => $file) {
7c89a18f
DP
543 $this->assertInstanceOf('stored_file', $file);
544 $this->assertEquals($key, $file->get_pathnamehash());
545 }
546
294d976e 547 // Don't recurse with dirs.
7c89a18f 548 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', false, true, 'id');
294d976e 549 // 3 files + 1 directory.
7c89a18f 550 $this->assertCount(4, $files);
294d976e 551 foreach ($files as $key => $file) {
7c89a18f
DP
552 $this->assertInstanceOf('stored_file', $file);
553 $this->assertEquals($key, $file->get_pathnamehash());
554 }
ac29403e 555
294d976e 556 // Recurse with dirs.
7c89a18f 557 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, true, 'id');
294d976e 558 // 3 files + 1 directory + 1 subdir file.
7c89a18f 559 $this->assertCount(5, $files);
294d976e 560 foreach ($files as $key => $file) {
7c89a18f
DP
561 $this->assertInstanceOf('stored_file', $file);
562 $this->assertEquals($key, $file->get_pathnamehash());
563 }
564
294d976e 565 // Recurse without dirs.
7c89a18f 566 $files = $fs->get_directory_files($user->ctxid, 'user', 'private', 0, '/', true, false, 'id');
294d976e 567 // 3 files + 1 subdir file.
7c89a18f 568 $this->assertCount(4, $files);
294d976e 569 foreach ($files as $key => $file) {
7c89a18f
DP
570 $this->assertInstanceOf('stored_file', $file);
571 $this->assertEquals($key, $file->get_pathnamehash());
572 }
ac29403e
DP
573 }
574
575 public function test_search_references() {
483afa44 576 $user = $this->setup_three_private_files();
ac29403e 577 $fs = get_file_storage();
483afa44
DM
578 $repos = repository::get_instances(array('type'=>'user'));
579 $repo = reset($repos);
ac29403e 580
483afa44
DM
581 $alias1 = array(
582 'contextid' => $user->ctxid,
583 'component' => 'user',
584 'filearea' => 'private',
585 'itemid' => 0,
586 'filepath' => '/aliases/',
587 'filename' => 'alias-to-1.txt'
588 );
589
590 $alias2 = array(
591 'contextid' => $user->ctxid,
592 'component' => 'user',
593 'filearea' => 'private',
594 'itemid' => 0,
595 'filepath' => '/aliases/',
596 'filename' => 'another-alias-to-1.txt'
597 );
598
599 $reference = file_storage::pack_reference(array(
600 'contextid' => $user->ctxid,
601 'component' => 'user',
602 'filearea' => 'private',
603 'itemid' => 0,
604 'filepath' => '/',
605 'filename' => '1.txt'
606 ));
607
608 // There are no aliases now.
609 $result = $fs->search_references($reference);
610 $this->assertEquals(array(), $result);
611
612 $result = $fs->search_references_count($reference);
613 $this->assertSame($result, 0);
614
615 // Create two aliases and make sure they are returned.
616 $fs->create_file_from_reference($alias1, $repo->id, $reference);
617 $fs->create_file_from_reference($alias2, $repo->id, $reference);
618
619 $result = $fs->search_references($reference);
620 $this->assertTrue(is_array($result));
621 $this->assertEquals(count($result), 2);
622 foreach ($result as $alias) {
623 $this->assertTrue($alias instanceof stored_file);
624 }
625
626 $result = $fs->search_references_count($reference);
627 $this->assertSame($result, 2);
628
629 // The method can't be used for references to files outside the filepool
630 $exceptionthrown = false;
631 try {
632 $fs->search_references('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg');
633 } catch (file_reference_exception $e) {
634 $exceptionthrown = true;
635 }
636 $this->assertTrue($exceptionthrown);
637
638 $exceptionthrown = false;
639 try {
640 $fs->search_references_count('http://dl.dropbox.com/download/1234567/naked-dougiamas.jpg');
641 } catch (file_reference_exception $e) {
642 $exceptionthrown = true;
643 }
644 $this->assertTrue($exceptionthrown);
ac29403e
DP
645 }
646
647 public function test_delete_area_files() {
648 $user = $this->setup_three_private_files();
649 $fs = get_file_storage();
650
651 // Get area files with default options.
652 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
653 // Should be the two files we added plus the folder.
654 $this->assertEquals(4, count($areafiles));
655 $fs->delete_area_files($user->ctxid, 'user', 'private');
656
657 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
658 // Should be the two files we added plus the folder.
659 $this->assertEquals(0, count($areafiles));
660 }
661
7c89a18f
DP
662 public function test_delete_area_files_itemid() {
663 $user = $this->setup_three_private_files();
664 $fs = get_file_storage();
665
666 // Get area files with default options.
667 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
668 // Should be the two files we added plus the folder.
669 $this->assertEquals(4, count($areafiles));
670 $fs->delete_area_files($user->ctxid, 'user', 'private', 9999);
671
672 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
673 $this->assertEquals(4, count($areafiles));
674 }
675
ac29403e
DP
676 public function test_delete_area_files_select() {
677 $user = $this->setup_three_private_files();
678 $fs = get_file_storage();
679
680 // Get area files with default options.
681 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
682 // Should be the two files we added plus the folder.
683 $this->assertEquals(4, count($areafiles));
684 $fs->delete_area_files_select($user->ctxid, 'user', 'private', '!= :notitemid', array('notitemid'=>9999));
685
686 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
687 // Should be the two files we added plus the folder.
688 $this->assertEquals(0, count($areafiles));
689 }
996f8b64 690
546b8864
DM
691 public function test_delete_component_files() {
692 $user = $this->setup_three_private_files();
693 $fs = get_file_storage();
694
695 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
696 $this->assertEquals(4, count($areafiles));
697 $fs->delete_component_files('user');
698 $areafiles = $fs->get_area_files($user->ctxid, 'user', 'private');
699 $this->assertEquals(0, count($areafiles));
700 }
701
996f8b64
DP
702 public function test_create_file_from_url() {
703 $this->resetAfterTest(true);
704
705 $syscontext = context_system::instance();
706 $filerecord = array(
707 'contextid' => $syscontext->id,
708 'component' => 'core',
709 'filearea' => 'unittest',
710 'itemid' => 0,
711 'filepath' => '/downloadtest/',
712 );
713 $url = 'http://download.moodle.org/unittest/test.html';
714
715 $fs = get_file_storage();
716
717 // Test creating file without filename.
718 $file1 = $fs->create_file_from_url($filerecord, $url);
719 $this->assertInstanceOf('stored_file', $file1);
720
721 // Set filename.
722 $filerecord['filename'] = 'unit-test-filename.html';
723 $file2 = $fs->create_file_from_url($filerecord, $url);
724 $this->assertInstanceOf('stored_file', $file2);
725
726 // Use temporary file.
727 $filerecord['filename'] = 'unit-test-with-temp-file.html';
728 $file3 = $fs->create_file_from_url($filerecord, $url, null, true);
729 $file3 = $this->assertInstanceOf('stored_file', $file3);
730 }
731
732 public function test_cron() {
733 $this->resetAfterTest(true);
734
735 // Note: this is only testing DB compatibility atm, rather than
294d976e 736 // that work is done.
996f8b64
DP
737 $fs = get_file_storage();
738
739 $this->expectOutputRegex('/Cleaning up/');
740 $fs->cron();
741 }
742
743 public function test_is_area_empty() {
744 $user = $this->setup_three_private_files();
745 $fs = get_file_storage();
746
747 $this->assertFalse($fs->is_area_empty($user->ctxid, 'user', 'private'));
748
749 // File area with madeup itemid should be empty.
750 $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999));
751 // Still empty with dirs included.
752 $this->assertTrue($fs->is_area_empty($user->ctxid, 'user', 'private', 9999, false));
753 }
754
755 public function test_move_area_files_to_new_context() {
756 $this->resetAfterTest(true);
757
758 // Create a course with a page resource.
759 $course = $this->getDataGenerator()->create_course();
760 $page1 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id));
761 $page1context = context_module::instance($page1->cmid);
762
996f8b64
DP
763 // Add a file to the page.
764 $fs = get_file_storage();
765 $filerecord = array(
766 'contextid' => $page1context->id,
767 'component' => 'mod_page',
768 'filearea' => 'content',
769 'itemid' => 0,
770 'filepath' => '/',
771 'filename' => 'unit-test-file.txt',
772 );
773
774 $originalfile = $fs->create_file_from_string($filerecord, 'Test content');
775 $this->assertInstanceOf('stored_file', $originalfile);
776
777 $pagefiles = $fs->get_area_files($page1context->id, 'mod_page', 'content', 0, 'sortorder', false);
778 // Should be one file in filearea.
779 $this->assertFalse($fs->is_area_empty($page1context->id, 'mod_page', 'content'));
780
781 // Create a new page.
782 $page2 = $this->getDataGenerator()->create_module('page', array('course'=>$course->id));
783 $page2context = context_module::instance($page2->cmid);
784
785 // Newly created page area is empty.
786 $this->assertTrue($fs->is_area_empty($page2context->id, 'mod_page', 'content'));
787
788 // Move the files.
789 $fs->move_area_files_to_new_context($page1context->id, $page2context->id, 'mod_page', 'content');
790
294d976e 791 // Page2 filearea should no longer be empty.
996f8b64
DP
792 $this->assertFalse($fs->is_area_empty($page2context->id, 'mod_page', 'content'));
793
294d976e 794 // Page1 filearea should now be empty.
996f8b64
DP
795 $this->assertTrue($fs->is_area_empty($page1context->id, 'mod_page', 'content'));
796
797 $page2files = $fs->get_area_files($page2context->id, 'mod_page', 'content', 0, 'sortorder', false);
798 $movedfile = reset($page2files);
799
294d976e 800 // The two files should have the same content hash.
996f8b64
DP
801 $this->assertEquals($movedfile->get_contenthash(), $originalfile->get_contenthash());
802 }
803
804 public function test_convert_image() {
805 global $CFG;
806
807 $this->resetAfterTest(false);
808
809 $filepath = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
810 $syscontext = context_system::instance();
811 $filerecord = array(
812 'contextid' => $syscontext->id,
813 'component' => 'core',
814 'filearea' => 'unittest',
815 'itemid' => 0,
816 'filepath' => '/images/',
817 'filename' => 'testimage.jpg',
818 );
819
820 $fs = get_file_storage();
821 $original = $fs->create_file_from_pathname($filerecord, $filepath);
822
823 $filerecord['filename'] = 'testimage-converted-10x10.jpg';
824 $converted = $fs->convert_image($filerecord, $original, 10, 10, true, 100);
825 $this->assertInstanceOf('stored_file', $converted);
826
827 $filerecord['filename'] = 'testimage-convereted-nosize.jpg';
828 $converted = $fs->convert_image($filerecord, $original);
829 $this->assertInstanceOf('stored_file', $converted);
830 }
831
832 private function generate_file_record() {
833 $syscontext = context_system::instance();
834 $filerecord = new stdClass();
835 $filerecord->contextid = $syscontext->id;
836 $filerecord->component = 'core';
837 $filerecord->filearea = 'phpunit';
838 $filerecord->filepath = '/';
839 $filerecord->filename = 'testfile.txt';
840 $filerecord->itemid = 0;
841
842 return $filerecord;
843 }
844
845 public function test_create_file_from_storedfile_file_invalid() {
846 $this->resetAfterTest(true);
847
848 $filerecord = $this->generate_file_record();
849
850 $fs = get_file_storage();
851 $this->setExpectedException('file_exception');
852 // Create a file from a file id which doesn't exist.
853 $fs->create_file_from_storedfile($filerecord, 9999);
854 }
855
856 public function test_create_file_from_storedfile_contextid_invalid() {
857 $this->resetAfterTest(true);
858
859 $filerecord = $this->generate_file_record();
860
861 $fs = get_file_storage();
862 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
863 $this->assertInstanceOf('stored_file', $file1);
864
865 $filerecord->filename = 'invalid.txt';
866 $filerecord->contextid = 'invalid';
867
868 $this->setExpectedException('file_exception', 'Invalid contextid');
869 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
870 }
871
872 public function test_create_file_from_storedfile_component_invalid() {
873 $this->resetAfterTest(true);
874
875 $filerecord = $this->generate_file_record();
876
877 $fs = get_file_storage();
878 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
879 $this->assertInstanceOf('stored_file', $file1);
880
881 $filerecord->filename = 'invalid.txt';
882 $filerecord->component = 'bad/component';
883
884 $this->setExpectedException('file_exception', 'Invalid component');
885 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
886 }
887
888 public function test_create_file_from_storedfile_filearea_invalid() {
889 $this->resetAfterTest(true);
890
891 $filerecord = $this->generate_file_record();
892
893 $fs = get_file_storage();
894 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
895 $this->assertInstanceOf('stored_file', $file1);
896
897 $filerecord->filename = 'invalid.txt';
898 $filerecord->filearea = 'bad-filearea';
899
900 $this->setExpectedException('file_exception', 'Invalid filearea');
901 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
902 }
903
904 public function test_create_file_from_storedfile_itemid_invalid() {
905 $this->resetAfterTest(true);
906
907 $filerecord = $this->generate_file_record();
908
909 $fs = get_file_storage();
910 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
911 $this->assertInstanceOf('stored_file', $file1);
912
913 $filerecord->filename = 'invalid.txt';
914 $filerecord->itemid = 'bad-itemid';
915
916 $this->setExpectedException('file_exception', 'Invalid itemid');
917 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
918 }
919
920 public function test_create_file_from_storedfile_filepath_invalid() {
921 $this->resetAfterTest(true);
922
923 $filerecord = $this->generate_file_record();
924
925 $fs = get_file_storage();
926 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
927 $this->assertInstanceOf('stored_file', $file1);
928
929 $filerecord->filename = 'invalid.txt';
930 $filerecord->filepath = 'a-/bad/-filepath';
931
932 $this->setExpectedException('file_exception', 'Invalid file path');
933 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
934 }
935
936 public function test_create_file_from_storedfile_filename_invalid() {
937 $this->resetAfterTest(true);
938
939 $filerecord = $this->generate_file_record();
940
941 $fs = get_file_storage();
942 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
943 $this->assertInstanceOf('stored_file', $file1);
944
945 $filerecord->filename = '';
946
947 $this->setExpectedException('file_exception', 'Invalid file name');
948 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
949 }
950
951 public function test_create_file_from_storedfile_timecreated_invalid() {
952 $this->resetAfterTest(true);
953
954 $filerecord = $this->generate_file_record();
955
956 $fs = get_file_storage();
957 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
958 $this->assertInstanceOf('stored_file', $file1);
959
960 $filerecord->filename = 'invalid.txt';
961 $filerecord->timecreated = 'today';
962
963 $this->setExpectedException('file_exception', 'Invalid file timecreated');
964 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
965 }
966
967 public function test_create_file_from_storedfile_timemodified_invalid() {
968 $this->resetAfterTest(true);
969
970 $filerecord = $this->generate_file_record();
971
972 $fs = get_file_storage();
973 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
974 $this->assertInstanceOf('stored_file', $file1);
975
976 $filerecord->filename = 'invalid.txt';
977 $filerecord->timemodified = 'today';
978
979 $this->setExpectedException('file_exception', 'Invalid file timemodified');
980 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
981 }
982
983 public function test_create_file_from_storedfile_duplicate() {
984 $this->resetAfterTest(true);
985
986 $filerecord = $this->generate_file_record();
987
988 $fs = get_file_storage();
989 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
990 $this->assertInstanceOf('stored_file', $file1);
991
992 // Creating a file validating unique constraint.
993 $this->setExpectedException('stored_file_creation_exception');
994 $fs->create_file_from_storedfile($filerecord, $file1->get_id());
995 }
996
997 public function test_create_file_from_storedfile() {
998 $this->resetAfterTest(true);
999
1000 $syscontext = context_system::instance();
1001
1002 $filerecord = new stdClass();
1003 $filerecord->contextid = $syscontext->id;
1004 $filerecord->component = 'core';
1005 $filerecord->filearea = 'phpunit';
1006 $filerecord->filepath = '/';
1007 $filerecord->filename = 'testfile.txt';
1008 $filerecord->itemid = 0;
1009
1010 $fs = get_file_storage();
1011
1012 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1013 $this->assertInstanceOf('stored_file', $file1);
1014
1015 $filerecord->filename = 'test-create-file-from-storedfile.txt';
1016 $file2 = $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1017 $this->assertInstanceOf('stored_file', $file2);
1018
1019 // These will be normalised to current time..
1020 $filerecord->timecreated = -100;
1021 $filerecord->timemodified= -100;
1022 $filerecord->filename = 'test-create-file-from-storedfile-bad-dates.txt';
1023
1024 $file3 = $fs->create_file_from_storedfile($filerecord, $file1->get_id());
1025 $this->assertInstanceOf('stored_file', $file3);
1026
1027 $this->assertNotEquals($file3->get_timemodified(), $filerecord->timemodified);
1028 $this->assertNotEquals($file3->get_timecreated(), $filerecord->timecreated);
1029 }
1030
1031 public function test_create_file_from_string_contextid_invalid() {
1032 $this->resetAfterTest(true);
1033
1034 $filerecord = $this->generate_file_record();
1035 $fs = get_file_storage();
1036
1037 $filerecord->contextid = 'invalid';
1038
1039 $this->setExpectedException('file_exception', 'Invalid contextid');
1040 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1041 }
1042
1043 public function test_create_file_from_string_component_invalid() {
1044 $this->resetAfterTest(true);
1045
1046 $filerecord = $this->generate_file_record();
1047 $fs = get_file_storage();
1048
1049 $filerecord->component = 'bad/component';
1050
1051 $this->setExpectedException('file_exception', 'Invalid component');
1052 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1053 }
1054
1055 public function test_create_file_from_string_filearea_invalid() {
1056 $this->resetAfterTest(true);
1057
1058 $filerecord = $this->generate_file_record();
1059 $fs = get_file_storage();
1060
1061 $filerecord->filearea = 'bad-filearea';
1062
1063 $this->setExpectedException('file_exception', 'Invalid filearea');
1064 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1065 }
1066
1067 public function test_create_file_from_string_itemid_invalid() {
1068 $this->resetAfterTest(true);
1069
1070 $filerecord = $this->generate_file_record();
1071 $fs = get_file_storage();
1072
1073 $filerecord->itemid = 'bad-itemid';
1074
1075 $this->setExpectedException('file_exception', 'Invalid itemid');
1076 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1077 }
1078
1079 public function test_create_file_from_string_filepath_invalid() {
1080 $this->resetAfterTest(true);
1081
1082 $filerecord = $this->generate_file_record();
1083 $fs = get_file_storage();
1084
1085 $filerecord->filepath = 'a-/bad/-filepath';
1086
1087 $this->setExpectedException('file_exception', 'Invalid file path');
1088 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1089 }
1090
1091 public function test_create_file_from_string_filename_invalid() {
1092 $this->resetAfterTest(true);
1093
1094 $filerecord = $this->generate_file_record();
1095 $fs = get_file_storage();
1096
1097 $filerecord->filename = '';
1098
1099 $this->setExpectedException('file_exception', 'Invalid file name');
1100 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1101 }
1102
1103 public function test_create_file_from_string_timecreated_invalid() {
1104 $this->resetAfterTest(true);
1105
1106 $filerecord = $this->generate_file_record();
1107 $fs = get_file_storage();
1108
1109 $filerecord->timecreated = 'today';
1110
1111 $this->setExpectedException('file_exception', 'Invalid file timecreated');
1112 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1113 }
1114
1115 public function test_create_file_from_string_timemodified_invalid() {
1116 $this->resetAfterTest(true);
1117
1118 $filerecord = $this->generate_file_record();
1119 $fs = get_file_storage();
1120
1121 $filerecord->timemodified = 'today';
1122
1123 $this->setExpectedException('file_exception', 'Invalid file timemodified');
1124 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1125 }
1126
1127 public function test_create_file_from_string_duplicate() {
1128 $this->resetAfterTest(true);
1129
1130 $filerecord = $this->generate_file_record();
1131 $fs = get_file_storage();
1132
1133 $file1 = $fs->create_file_from_string($filerecord, 'text contents');
1134
1135 // Creating a file validating unique constraint.
1136 $this->setExpectedException('stored_file_creation_exception');
1137 $file2 = $fs->create_file_from_string($filerecord, 'text contents');
1138 }
1139
1140 public function test_create_file_from_pathname_contextid_invalid() {
1141 global $CFG;
1142 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1143
1144 $this->resetAfterTest(true);
1145
1146 $filerecord = $this->generate_file_record();
1147 $fs = get_file_storage();
1148
1149 $filerecord->contextid = 'invalid';
1150
1151 $this->setExpectedException('file_exception', 'Invalid contextid');
1152 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1153 }
1154
1155 public function test_create_file_from_pathname_component_invalid() {
1156 global $CFG;
1157 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1158
1159 $this->resetAfterTest(true);
1160
1161 $filerecord = $this->generate_file_record();
1162 $fs = get_file_storage();
1163
1164 $filerecord->component = 'bad/component';
1165
1166 $this->setExpectedException('file_exception', 'Invalid component');
1167 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1168 }
1169
1170 public function test_create_file_from_pathname_filearea_invalid() {
1171 global $CFG;
1172 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1173
1174 $this->resetAfterTest(true);
1175
1176 $filerecord = $this->generate_file_record();
1177 $fs = get_file_storage();
1178
1179 $filerecord->filearea = 'bad-filearea';
1180
1181 $this->setExpectedException('file_exception', 'Invalid filearea');
1182 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1183 }
1184
1185 public function test_create_file_from_pathname_itemid_invalid() {
1186 global $CFG;
1187 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1188
1189 $this->resetAfterTest(true);
1190
1191 $filerecord = $this->generate_file_record();
1192 $fs = get_file_storage();
1193
1194 $filerecord->itemid = 'bad-itemid';
1195
1196 $this->setExpectedException('file_exception', 'Invalid itemid');
1197 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1198 }
1199
1200 public function test_create_file_from_pathname_filepath_invalid() {
1201 global $CFG;
1202 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1203
1204 $this->resetAfterTest(true);
1205
1206 $filerecord = $this->generate_file_record();
1207 $fs = get_file_storage();
1208
1209 $filerecord->filepath = 'a-/bad/-filepath';
1210
1211 $this->setExpectedException('file_exception', 'Invalid file path');
1212 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1213 }
1214
1215 public function test_create_file_from_pathname_filename_invalid() {
1216 global $CFG;
1217 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1218
1219 $this->resetAfterTest(true);
1220
1221 $filerecord = $this->generate_file_record();
1222 $fs = get_file_storage();
1223
1224 $filerecord->filename = '';
1225
1226 $this->setExpectedException('file_exception', 'Invalid file name');
1227 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1228 }
1229
1230 public function test_create_file_from_pathname_timecreated_invalid() {
1231 global $CFG;
1232 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1233
1234 $this->resetAfterTest(true);
1235
1236 $filerecord = $this->generate_file_record();
1237 $fs = get_file_storage();
1238
1239 $filerecord->timecreated = 'today';
1240
1241 $this->setExpectedException('file_exception', 'Invalid file timecreated');
1242 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1243 }
1244
1245 public function test_create_file_from_pathname_timemodified_invalid() {
1246 global $CFG;
1247 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1248
1249 $this->resetAfterTest(true);
1250
1251 $filerecord = $this->generate_file_record();
1252 $fs = get_file_storage();
1253
1254 $filerecord->timemodified = 'today';
1255
1256 $this->setExpectedException('file_exception', 'Invalid file timemodified');
1257 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1258 }
1259
1260 public function test_create_file_from_pathname_duplicate_file() {
1261 global $CFG;
1262 $this->resetAfterTest(true);
1263
1264 $path = $CFG->dirroot.'/lib/filestorage/tests/fixtures/testimage.jpg';
1265
1266 $filerecord = $this->generate_file_record();
1267 $fs = get_file_storage();
1268
1269 $file1 = $fs->create_file_from_pathname($filerecord, $path);
1270 $this->assertInstanceOf('stored_file', $file1);
1271
1272 // Creating a file validating unique constraint.
1273 $this->setExpectedException('stored_file_creation_exception');
1274 $file2 = $fs->create_file_from_pathname($filerecord, $path);
1275 }
2d2c194b
DM
1276
1277 /**
1278 * Calling stored_file::delete_reference() on a non-reference file throws coding_exception
1279 */
1280 public function test_delete_reference_on_nonreference() {
1281
1282 $this->resetAfterTest(true);
1283 $user = $this->setup_three_private_files();
1284 $fs = get_file_storage();
1285 $repos = repository::get_instances(array('type'=>'user'));
1286 $repo = reset($repos);
1287
1288 $file = null;
1289 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
1290 if (!$areafile->is_directory()) {
1291 $file = $areafile;
1292 break;
1293 }
1294 }
1295 $this->assertInstanceOf('stored_file', $file);
1296 $this->assertFalse($file->is_external_file());
1297
1298 $this->setExpectedException('coding_exception');
1299 $file->delete_reference();
1300 }
1301
1302 /**
1303 * Calling stored_file::delete_reference() on a reference file does not affect other
1304 * symlinks to the same original
1305 */
1306 public function test_delete_reference_one_symlink_does_not_rule_them_all() {
1307
1308 $this->resetAfterTest(true);
1309 $user = $this->setup_three_private_files();
1310 $fs = get_file_storage();
1311 $repos = repository::get_instances(array('type'=>'user'));
1312 $repo = reset($repos);
1313
1314 // create two aliases linking the same original
1315
1316 $originalfile = null;
1317 foreach ($fs->get_area_files($user->ctxid, 'user', 'private') as $areafile) {
1318 if (!$areafile->is_directory()) {
1319 $originalfile = $areafile;
1320 break;
1321 }
1322 }
1323 $this->assertInstanceOf('stored_file', $originalfile);
1324
1325 // calling delete_reference() on a non-reference file
1326
1327 $originalrecord = array(
1328 'contextid' => $originalfile->get_contextid(),
1329 'component' => $originalfile->get_component(),
1330 'filearea' => $originalfile->get_filearea(),
1331 'itemid' => $originalfile->get_itemid(),
1332 'filepath' => $originalfile->get_filepath(),
1333 'filename' => $originalfile->get_filename(),
1334 );
1335
1336 $aliasrecord = $this->generate_file_record();
1337 $aliasrecord->filepath = '/A/';
1338 $aliasrecord->filename = 'symlink.txt';
1339
1340 $ref = $fs->pack_reference($originalrecord);
1341 $aliasfile1 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1342
1343 $aliasrecord->filepath = '/B/';
1344 $aliasrecord->filename = 'symlink.txt';
1345 $ref = $fs->pack_reference($originalrecord);
1346 $aliasfile2 = $fs->create_file_from_reference($aliasrecord, $repo->id, $ref);
1347
1348 // refetch A/symlink.txt
1349 $symlink1 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1350 $aliasrecord->filearea, $aliasrecord->itemid, '/A/', 'symlink.txt');
1351 $this->assertTrue($symlink1->is_external_file());
1352
1353 // unlink the A/symlink.txt
1354 $symlink1->delete_reference();
1355 $this->assertFalse($symlink1->is_external_file());
1356
1357 // make sure that B/symlink.txt has not been affected
1358 $symlink2 = $fs->get_file($aliasrecord->contextid, $aliasrecord->component,
1359 $aliasrecord->filearea, $aliasrecord->itemid, '/B/', 'symlink.txt');
1360 $this->assertTrue($symlink2->is_external_file());
1361 }
3385a89c
FM
1362
1363 public function test_get_unused_filename() {
1364 global $USER;
1365 $this->resetAfterTest(true);
1366
1367 $fs = get_file_storage();
1368 $this->setAdminUser();
1369 $contextid = context_user::instance($USER->id)->id;
1370 $component = 'user';
1371 $filearea = 'private';
1372 $itemid = 0;
1373 $filepath = '/';
1374
1375 // Create some private files.
1376 $file = new stdClass;
1377 $file->contextid = $contextid;
1378 $file->component = 'user';
1379 $file->filearea = 'private';
1380 $file->itemid = 0;
1381 $file->filepath = '/';
1382 $file->source = 'test';
1383 $filenames = array('foo.txt', 'foo (1).txt', 'foo (20).txt', 'foo (999)', 'bar.jpg', 'What (a cool file).jpg',
1384 'Hurray! (1).php', 'Hurray! (2).php', 'Hurray! (9a).php', 'Hurray! (abc).php');
1385 foreach ($filenames as $key => $filename) {
1386 $file->filename = $filename;
1387 $userfile = $fs->create_file_from_string($file, "file $key $filename content");
1388 $this->assertInstanceOf('stored_file', $userfile);
1389 }
1390
1391 // Asserting new generated names.
1392 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'unused.txt');
1393 $this->assertEquals('unused.txt', $newfilename);
1394 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo.txt');
1395 $this->assertEquals('foo (21).txt', $newfilename);
1396 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (1).txt');
1397 $this->assertEquals('foo (21).txt', $newfilename);
1398 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (2).txt');
1399 $this->assertEquals('foo (2).txt', $newfilename);
1400 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (20).txt');
1401 $this->assertEquals('foo (21).txt', $newfilename);
1402 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo');
1403 $this->assertEquals('foo', $newfilename);
1404 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (123)');
1405 $this->assertEquals('foo (123)', $newfilename);
1406 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'foo (999)');
1407 $this->assertEquals('foo (1000)', $newfilename);
1408 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.png');
1409 $this->assertEquals('bar.png', $newfilename);
1410 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (12).png');
1411 $this->assertEquals('bar (12).png', $newfilename);
1412 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar.jpg');
1413 $this->assertEquals('bar (1).jpg', $newfilename);
1414 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'bar (1).jpg');
1415 $this->assertEquals('bar (1).jpg', $newfilename);
1416 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'What (a cool file).jpg');
1417 $this->assertEquals('What (a cool file) (1).jpg', $newfilename);
1418 $newfilename = $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, 'Hurray! (1).php');
1419 $this->assertEquals('Hurray! (3).php', $newfilename);
1420
1421 $this->setExpectedException('coding_exception');
1422 $fs->get_unused_filename($contextid, $component, $filearea, $itemid, $filepath, '');
1423 }
1424
8f110835 1425}