Merge branch 'MDL-44095' of https://github.com/shashirepo/moodle
[moodle.git] / repository / tests / repositorylib_test.php
blobac161d1a4078bdb0d4cdf09baa4a8969f071ecd3
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Repository API unit tests
20 * @package repository
21 * @category phpunit
22 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once("$CFG->dirroot/repository/lib.php");
31 class core_repositorylib_testcase extends advanced_testcase {
33 /**
34 * Installing repository tests
36 * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
38 public function test_install_repository() {
39 global $CFG, $DB;
41 $this->resetAfterTest(true);
43 $syscontext = context_system::instance();
44 $repositorypluginname = 'boxnet';
45 // override repository permission
46 $capability = 'repository/' . $repositorypluginname . ':view';
47 $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id');
48 assign_capability($capability, CAP_ALLOW, $allroles['guest'], $syscontext->id, true);
50 $plugintype = new repository_type($repositorypluginname);
51 $pluginid = $plugintype->create(false);
52 $this->assertInternalType('int', $pluginid);
53 $args = array();
54 $args['type'] = $repositorypluginname;
55 $repos = repository::get_instances($args);
56 $repository = reset($repos);
57 $this->assertInstanceOf('repository', $repository);
58 $info = $repository->get_meta();
59 $this->assertEquals($repositorypluginname, $info->type);
62 public function test_get_unused_filename() {
63 global $USER;
65 $this->resetAfterTest(true);
67 $this->setAdminUser();
68 $fs = get_file_storage();
70 $draftitemid = null;
71 $context = context_user::instance($USER->id);
72 file_prepare_draft_area($draftitemid, $context->id, 'phpunit', 'test_get_unused_filename', 1);
74 $dummy = array(
75 'contextid' => $context->id,
76 'component' => 'user',
77 'filearea' => 'draft',
78 'itemid' => $draftitemid,
79 'filepath' => '/',
80 'filename' => ''
83 // Create some files.
84 $existingfiles = array(
85 'test',
86 'test.txt',
87 'test (1).txt',
88 'test1.txt',
89 'test1 (1).txt',
90 'test1 (2).txt',
91 'test1 (3).txt',
92 'test1 (My name is Bob).txt',
93 'test2 (555).txt',
94 'test3 (1000).txt',
95 'test3 (1000MB).txt',
97 foreach ($existingfiles as $filename) {
98 $dummy['filename'] = $filename;
99 $file = $fs->create_file_from_string($dummy, 'blah! ' . $filename);
100 $this->assertTrue(repository::draftfile_exists($draftitemid, '/', $filename));
103 // Actual testing.
104 $this->assertEquals('free.txt', repository::get_unused_filename($draftitemid, '/', 'free.txt'));
105 $this->assertEquals('test (1)', repository::get_unused_filename($draftitemid, '/', 'test'));
106 $this->assertEquals('test (2).txt', repository::get_unused_filename($draftitemid, '/', 'test.txt'));
107 $this->assertEquals('test1 (4).txt', repository::get_unused_filename($draftitemid, '/', 'test1.txt'));
108 $this->assertEquals('test1 (8).txt', repository::get_unused_filename($draftitemid, '/', 'test1 (8).txt'));
109 $this->assertEquals('test1 ().txt', repository::get_unused_filename($draftitemid, '/', 'test1 ().txt'));
110 $this->assertEquals('test2 (556).txt', repository::get_unused_filename($draftitemid, '/', 'test2 (555).txt'));
111 $this->assertEquals('test3 (1001).txt', repository::get_unused_filename($draftitemid, '/', 'test3 (1000).txt'));
112 $this->assertEquals('test3 (1000MB) (1).txt', repository::get_unused_filename($draftitemid, '/', 'test3 (1000MB).txt'));
113 $this->assertEquals('test4 (1).txt', repository::get_unused_filename($draftitemid, '/', 'test4 (1).txt'));
116 public function test_draftfile_exists() {
117 global $USER;
119 $this->resetAfterTest(true);
121 $this->setAdminUser();
122 $fs = get_file_storage();
124 $draftitemid = file_get_unused_draft_itemid();
125 $context = context_user::instance($USER->id);
127 $dummy = array(
128 'contextid' => $context->id,
129 'component' => 'user',
130 'filearea' => 'draft',
131 'itemid' => $draftitemid,
132 'filepath' => '/',
133 'filename' => ''
136 // Create some files.
137 $existingfiles = array(
138 'The Matrix.movie',
139 'Astalavista.txt',
140 'foobar',
142 foreach ($existingfiles as $filename) {
143 $dummy['filename'] = $filename;
144 $file = $fs->create_file_from_string($dummy, 'Content of ' . $filename);
145 $this->assertInstanceOf('stored_file', $file);
148 // Doing the text.
149 foreach ($existingfiles as $filename) {
150 $this->assertTrue(repository::draftfile_exists($draftitemid, '/', $filename));
152 foreach (array('Terminator.movie', 'Where is Wally?', 'barfoo') as $filename) {
153 $this->assertFalse(repository::draftfile_exists($draftitemid, '/', $filename));
157 public function test_can_be_edited_by_user() {
158 $this->resetAfterTest(true);
160 $syscontext = context_system::instance();
161 $course = $this->getDataGenerator()->create_course();
162 $coursecontext = context_course::instance($course->id);
163 $roleid = create_role('A role', 'arole', 'A role', '');
164 $user = $this->getDataGenerator()->create_user();
165 $this->setUser($user);
167 // Instance on a site level.
168 $this->getDataGenerator()->create_repository_type('flickr_public');
169 $repoid = $this->getDataGenerator()->create_repository('flickr_public')->id;
170 $systemrepo = repository::get_repository_by_id($repoid, $syscontext);
172 role_assign($roleid, $user->id, $syscontext->id);
173 assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext, true);
174 assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
175 accesslib_clear_all_caches_for_unit_testing();
176 $this->assertTrue($systemrepo->can_be_edited_by_user());
178 assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $syscontext, true);
179 assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $syscontext, true);
180 accesslib_clear_all_caches_for_unit_testing();
181 $this->assertFalse($systemrepo->can_be_edited_by_user());
183 assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
184 assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $syscontext, true);
185 accesslib_clear_all_caches_for_unit_testing();
186 $this->assertFalse($systemrepo->can_be_edited_by_user());
188 role_unassign($roleid, $user->id, $syscontext->id);
189 accesslib_clear_all_caches_for_unit_testing();
191 // Instance on a course level.
192 $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleid);
194 $params = array('contextid' => $coursecontext->id);
195 $repoid = $this->getDataGenerator()->create_repository('flickr_public', $params)->id;
196 $courserepo = repository::get_repository_by_id($repoid, $coursecontext);
198 assign_capability('moodle/course:update', CAP_ALLOW, $roleid, $coursecontext, true);
199 assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $coursecontext, true);
200 accesslib_clear_all_caches_for_unit_testing();
201 $this->assertTrue($courserepo->can_be_edited_by_user());
203 assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $coursecontext, true);
204 accesslib_clear_all_caches_for_unit_testing();
205 $this->assertFalse($courserepo->can_be_edited_by_user());
207 assign_capability('moodle/course:update', CAP_ALLOW, $roleid, $coursecontext, true);
208 assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $coursecontext, true);
209 accesslib_clear_all_caches_for_unit_testing();
210 $this->assertFalse($courserepo->can_be_edited_by_user());
212 role_unassign($roleid, $user->id, $coursecontext->id);
213 accesslib_clear_all_caches_for_unit_testing();
215 // Instance on a user level.
216 $otheruser = $this->getDataGenerator()->create_user();
217 $otherusercontext = context_user::instance($otheruser->id);
218 role_assign($roleid, $user->id, $syscontext->id);
219 assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
220 accesslib_clear_all_caches_for_unit_testing();
222 // Editing someone else's instance.
223 $record = array('contextid' => $otherusercontext->id);
224 $repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
225 $userrepo = repository::get_repository_by_id($repoid, $syscontext);
226 $this->assertFalse($userrepo->can_be_edited_by_user());
228 // Editing my own instance.
229 $usercontext = context_user::instance($user->id);
230 $record = array('contextid' => $usercontext->id);
231 $repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
232 $userrepo = repository::get_repository_by_id($repoid, $syscontext);
233 $this->assertTrue($userrepo->can_be_edited_by_user());
237 public function test_check_capability() {
238 $this->resetAfterTest(true);
240 $syscontext = context_system::instance();
241 $course1 = $this->getDataGenerator()->create_course();
242 $course1context = context_course::instance($course1->id);
243 $course2 = $this->getDataGenerator()->create_course();
244 $course2context = context_course::instance($course2->id);
246 $forumdata = new stdClass();
247 $forumdata->course = $course1->id;
248 $forumc1 = $this->getDataGenerator()->create_module('forum', $forumdata);
249 $forumc1context = context_module::instance($forumc1->cmid);
250 $forumdata->course = $course2->id;
251 $forumc2 = $this->getDataGenerator()->create_module('forum', $forumdata);
252 $forumc2context = context_module::instance($forumc2->cmid);
254 $blockdata = new stdClass();
255 $blockdata->parentcontextid = $course1context->id;
256 $blockc1 = $this->getDataGenerator()->create_block('online_users', $blockdata);
257 $blockc1context = context_block::instance($blockc1->id);
258 $blockdata->parentcontextid = $course2context->id;
259 $blockc2 = $this->getDataGenerator()->create_block('online_users', $blockdata);
260 $blockc2context = context_block::instance($blockc2->id);
262 $user1 = $this->getDataGenerator()->create_user();
263 $user1context = context_user::instance($user1->id);
264 $user2 = $this->getDataGenerator()->create_user();
265 $user2context = context_user::instance($user2->id);
267 // New role prohibiting Flickr Public access.
268 $roleid = create_role('No Flickr Public', 'noflickrpublic', 'No Flickr Public', '');
269 assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $syscontext, true);
271 // Disallow system access to Flickr Public to user 2.
272 role_assign($roleid, $user2->id, $syscontext->id);
273 accesslib_clear_all_caches_for_unit_testing();
275 // Enable repositories.
276 $this->getDataGenerator()->create_repository_type('flickr_public');
277 $this->getDataGenerator()->create_repository_type('dropbox');
279 // Instance on a site level.
280 $repoid = $this->getDataGenerator()->create_repository('flickr_public')->id;
281 $systemrepo = repository::get_repository_by_id($repoid, $syscontext);
283 // Check that everyone with right capability can view a site-wide repository.
284 $this->setUser($user1);
285 $this->assertTrue($systemrepo->check_capability());
287 // Without the capability, we cannot view a site-wide repository.
288 $this->setUser($user2);
289 $caughtexception = false;
290 try {
291 $systemrepo->check_capability();
292 } catch (repository_exception $e) {
293 $caughtexception = true;
295 $this->assertTrue($caughtexception);
297 // Instance on a course level.
298 $record = new stdClass();
299 $record->contextid = $course1context->id;
300 $courserepoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
302 // Within the course, I can view the repository.
303 $courserepo = repository::get_repository_by_id($courserepoid, $course1context);
304 $this->setUser($user1);
305 $this->assertTrue($courserepo->check_capability());
306 // But not without the capability.
307 $this->setUser($user2);
308 $caughtexception = false;
309 try {
310 $courserepo->check_capability();
311 } catch (repository_exception $e) {
312 $caughtexception = true;
314 $this->assertTrue($caughtexception);
316 // From another course I cannot, with or without the capability.
317 $courserepo = repository::get_repository_by_id($courserepoid, $course2context);
318 $this->setUser($user1);
319 $caughtexception = false;
320 try {
321 $courserepo->check_capability();
322 } catch (repository_exception $e) {
323 $caughtexception = true;
325 $this->assertTrue($caughtexception);
326 $this->setUser($user2);
327 $caughtexception = false;
328 try {
329 $courserepo->check_capability();
330 } catch (repository_exception $e) {
331 $caughtexception = true;
333 $this->assertTrue($caughtexception);
335 // From a module within the course, I can view the repository.
336 $courserepo = repository::get_repository_by_id($courserepoid, $forumc1context);
337 $this->setUser($user1);
338 $this->assertTrue($courserepo->check_capability());
339 // But not without the capability.
340 $this->setUser($user2);
341 $caughtexception = false;
342 try {
343 $courserepo->check_capability();
344 } catch (repository_exception $e) {
345 $caughtexception = true;
347 $this->assertTrue($caughtexception);
349 // From a module in the wrong course, I cannot view the repository.
350 $courserepo = repository::get_repository_by_id($courserepoid, $forumc2context);
351 $this->setUser($user1);
352 $caughtexception = false;
353 try {
354 $courserepo->check_capability();
355 } catch (repository_exception $e) {
356 $caughtexception = true;
358 $this->assertTrue($caughtexception);
360 // From a block within the course, I can view the repository.
361 $courserepo = repository::get_repository_by_id($courserepoid, $blockc1context);
362 $this->setUser($user1);
363 $this->assertTrue($courserepo->check_capability());
364 // But not without the capability.
365 $this->setUser($user2);
366 $caughtexception = false;
367 try {
368 $courserepo->check_capability();
369 } catch (repository_exception $e) {
370 $caughtexception = true;
372 $this->assertTrue($caughtexception);
374 // From a block in the wrong course, I cannot view the repository.
375 $courserepo = repository::get_repository_by_id($courserepoid, $blockc2context);
376 $this->setUser($user1);
377 $caughtexception = false;
378 try {
379 $courserepo->check_capability();
380 } catch (repository_exception $e) {
381 $caughtexception = true;
383 $this->assertTrue($caughtexception);
385 // Instance on a user level.
386 // Instance on a course level.
387 $record = new stdClass();
388 $record->contextid = $user1context->id;
389 $user1repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
390 $record->contextid = $user2context->id;
391 $user2repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
393 // Check that a user can see its own repository.
394 $userrepo = repository::get_repository_by_id($user1repoid, $syscontext);
395 $this->setUser($user1);
396 $this->assertTrue($userrepo->check_capability());
397 // But not without the capability.
398 $userrepo = repository::get_repository_by_id($user2repoid, $syscontext);
399 $this->setUser($user2);
400 $caughtexception = false;
401 try {
402 $userrepo->check_capability();
403 } catch (repository_exception $e) {
404 $caughtexception = true;
406 $this->assertTrue($caughtexception);
408 // Check that a user cannot see someone's repository.
409 $userrepo = repository::get_repository_by_id($user2repoid, $syscontext);
410 $this->setUser($user1);
411 $caughtexception = false;
412 try {
413 $userrepo->check_capability();
414 } catch (repository_exception $e) {
415 $caughtexception = true;
417 $this->assertTrue($caughtexception);
418 // Make sure the repo from user 2 was accessible.
419 role_unassign($roleid, $user2->id, $syscontext->id);
420 accesslib_clear_all_caches_for_unit_testing();
421 $this->setUser($user2);
422 $this->assertTrue($userrepo->check_capability());
423 role_assign($roleid, $user2->id, $syscontext->id);
424 accesslib_clear_all_caches_for_unit_testing();
426 // Check that a user can view SOME repositories when logged in as someone else.
427 $params = new stdClass();
428 $params->name = 'Dropbox';
429 $params->dropbox_key = 'key';
430 $params->dropbox_secret = 'secret';
431 $privaterepoid = $this->getDataGenerator()->create_repository('dropbox')->id;
432 $notprivaterepoid = $this->getDataGenerator()->create_repository('upload')->id;
434 $privaterepo = repository::get_repository_by_id($privaterepoid, $syscontext);
435 $notprivaterepo = repository::get_repository_by_id($notprivaterepoid, $syscontext);
436 $userrepo = repository::get_repository_by_id($user1repoid, $syscontext);
438 $this->setAdminUser();
439 \core\session\manager::loginas($user1->id, $syscontext);
441 // Logged in as, I cannot view a user instance.
442 $caughtexception = false;
443 try {
444 $userrepo->check_capability();
445 } catch (repository_exception $e) {
446 $caughtexception = true;
448 $this->assertTrue($caughtexception);
450 // Logged in as, I cannot view a private instance.
451 $caughtexception = false;
452 try {
453 $privaterepo->check_capability();
454 } catch (repository_exception $e) {
455 $caughtexception = true;
457 $this->assertTrue($caughtexception);
459 // Logged in as, I can view a non-private instance.
460 $this->assertTrue($notprivaterepo->check_capability());
463 function test_delete_all_for_context() {
464 global $DB;
465 $this->resetAfterTest(true);
467 $this->setAdminUser();
468 $course = $this->getDataGenerator()->create_course();
469 $user = $this->getDataGenerator()->create_user();
470 $this->getDataGenerator()->create_repository_type('flickr_public');
471 $this->getDataGenerator()->create_repository_type('filesystem');
472 $coursecontext = context_course::instance($course->id);
473 $usercontext = context_user::instance($user->id);
475 // Creating course instances.
476 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
477 $courserepo1 = repository::get_repository_by_id($repo->id, $coursecontext);
478 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
480 $repo = $this->getDataGenerator()->create_repository('filesystem', array('contextid' => $coursecontext->id));
481 $courserepo2 = repository::get_repository_by_id($repo->id, $coursecontext);
482 $this->assertEquals(2, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
484 // Creating user instances.
485 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
486 $userrepo1 = repository::get_repository_by_id($repo->id, $usercontext);
487 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
489 $repo = $this->getDataGenerator()->create_repository('filesystem', array('contextid' => $usercontext->id));
490 $userrepo2 = repository::get_repository_by_id($repo->id, $usercontext);
491 $this->assertEquals(2, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
493 // Simulation of course deletion.
494 repository::delete_all_for_context($coursecontext->id);
495 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
496 $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $courserepo1->id)));
497 $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $courserepo2->id)));
498 $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $courserepo1->id)));
499 $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $courserepo2->id)));
501 // Simulation of user deletion.
502 repository::delete_all_for_context($usercontext->id);
503 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
504 $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $userrepo1->id)));
505 $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $userrepo2->id)));
506 $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $userrepo1->id)));
507 $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $userrepo2->id)));
509 // Checking deletion upon course context deletion.
510 $course = $this->getDataGenerator()->create_course();
511 $coursecontext = context_course::instance($course->id);
512 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
513 $courserepo = repository::get_repository_by_id($repo->id, $coursecontext);
514 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
515 $coursecontext->delete();
516 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
518 // Checking deletion upon user context deletion.
519 $user = $this->getDataGenerator()->create_user();
520 $usercontext = context_user::instance($user->id);
521 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
522 $userrepo = repository::get_repository_by_id($repo->id, $usercontext);
523 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
524 $usercontext->delete();
525 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
527 // Checking deletion upon course deletion.
528 $course = $this->getDataGenerator()->create_course();
529 $coursecontext = context_course::instance($course->id);
530 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
531 $courserepo = repository::get_repository_by_id($repo->id, $coursecontext);
532 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
533 delete_course($course, false);
534 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
536 // Checking deletion upon user deletion.
537 $user = $this->getDataGenerator()->create_user();
538 $usercontext = context_user::instance($user->id);
539 $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
540 $userrepo = repository::get_repository_by_id($repo->id, $usercontext);
541 $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
542 delete_user($user);
543 $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));