Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]

   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.
  13  //
  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/>.
  16  
  17  namespace core_repository;
  18  
  19  use repository;
  20  use repository_exception;
  21  use repository_type;
  22  
  23  defined('MOODLE_INTERNAL') || die();
  24  
  25  global $CFG;
  26  require_once("$CFG->dirroot/repository/lib.php");
  27  
  28  /**
  29   * Repository API unit tests
  30   *
  31   * @package   core_repository
  32   * @category  test
  33   * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
  34   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class repositorylib_test extends \advanced_testcase {
  37  
  38      /**
  39       * Installing repository tests
  40       *
  41       * @copyright 2012 Dongsheng Cai {@link http://dongsheng.org}
  42       */
  43      public function test_install_repository() {
  44          global $CFG, $DB;
  45  
  46          $this->resetAfterTest(true);
  47  
  48          $syscontext = \context_system::instance();
  49          $repositorypluginname = 'dropbox';
  50          // override repository permission
  51          $capability = 'repository/' . $repositorypluginname . ':view';
  52          $guestroleid = $DB->get_field('role', 'id', array('shortname' => 'guest'));
  53          assign_capability($capability, CAP_ALLOW, $guestroleid, $syscontext->id, true);
  54  
  55          $plugintype = new repository_type($repositorypluginname);
  56          $pluginid = $plugintype->create(false);
  57          $this->assertIsInt($pluginid);
  58          $args = array();
  59          $args['type'] = $repositorypluginname;
  60          $repos = repository::get_instances($args);
  61          $repository = reset($repos);
  62          $this->assertInstanceOf('repository', $repository);
  63          $info = $repository->get_meta();
  64          $this->assertEquals($repositorypluginname, $info->type);
  65      }
  66  
  67      public function test_get_unused_filename() {
  68          global $USER;
  69  
  70          $this->resetAfterTest(true);
  71  
  72          $this->setAdminUser();
  73          $fs = get_file_storage();
  74  
  75          $draftitemid = null;
  76          $context = \context_user::instance($USER->id);
  77          file_prepare_draft_area($draftitemid, $context->id, 'phpunit', 'test_get_unused_filename', 1);
  78  
  79          $dummy = array(
  80              'contextid' => $context->id,
  81              'component' => 'user',
  82              'filearea' => 'draft',
  83              'itemid' => $draftitemid,
  84              'filepath' => '/',
  85              'filename' => ''
  86          );
  87  
  88          // Create some files.
  89          $existingfiles = array(
  90              'test',
  91              'test.txt',
  92              'test (1).txt',
  93              'test1.txt',
  94              'test1 (1).txt',
  95              'test1 (2).txt',
  96              'test1 (3).txt',
  97              'test1 (My name is Bob).txt',
  98              'test2 (555).txt',
  99              'test3 (1000).txt',
 100              'test3 (1000MB).txt',
 101          );
 102          foreach ($existingfiles as $filename) {
 103              $dummy['filename'] = $filename;
 104              $file = $fs->create_file_from_string($dummy, 'blah! ' . $filename);
 105              $this->assertTrue(repository::draftfile_exists($draftitemid, '/', $filename));
 106          }
 107  
 108          // Actual testing.
 109          $this->assertEquals('free.txt', repository::get_unused_filename($draftitemid, '/', 'free.txt'));
 110          $this->assertEquals('test (1)', repository::get_unused_filename($draftitemid, '/', 'test'));
 111          $this->assertEquals('test (2).txt', repository::get_unused_filename($draftitemid, '/', 'test.txt'));
 112          $this->assertEquals('test1 (4).txt', repository::get_unused_filename($draftitemid, '/', 'test1.txt'));
 113          $this->assertEquals('test1 (8).txt', repository::get_unused_filename($draftitemid, '/', 'test1 (8).txt'));
 114          $this->assertEquals('test1 ().txt', repository::get_unused_filename($draftitemid, '/', 'test1 ().txt'));
 115          $this->assertEquals('test2 (556).txt', repository::get_unused_filename($draftitemid, '/', 'test2 (555).txt'));
 116          $this->assertEquals('test3 (1001).txt', repository::get_unused_filename($draftitemid, '/', 'test3 (1000).txt'));
 117          $this->assertEquals('test3 (1000MB) (1).txt', repository::get_unused_filename($draftitemid, '/', 'test3 (1000MB).txt'));
 118          $this->assertEquals('test4 (1).txt', repository::get_unused_filename($draftitemid, '/', 'test4 (1).txt'));
 119      }
 120  
 121      public function test_draftfile_exists() {
 122          global $USER;
 123  
 124          $this->resetAfterTest(true);
 125  
 126          $this->setAdminUser();
 127          $fs = get_file_storage();
 128  
 129          $draftitemid = file_get_unused_draft_itemid();
 130          $context = \context_user::instance($USER->id);
 131  
 132          $dummy = array(
 133              'contextid' => $context->id,
 134              'component' => 'user',
 135              'filearea' => 'draft',
 136              'itemid' => $draftitemid,
 137              'filepath' => '/',
 138              'filename' => ''
 139          );
 140  
 141          // Create some files.
 142          $existingfiles = array(
 143              'The Matrix.movie',
 144              'Astalavista.txt',
 145              'foobar',
 146          );
 147          foreach ($existingfiles as $filename) {
 148              $dummy['filename'] = $filename;
 149              $file = $fs->create_file_from_string($dummy, 'Content of ' . $filename);
 150              $this->assertInstanceOf('stored_file', $file);
 151          }
 152  
 153          // Doing the text.
 154          foreach ($existingfiles as $filename) {
 155              $this->assertTrue(repository::draftfile_exists($draftitemid, '/', $filename));
 156          }
 157          foreach (array('Terminator.movie', 'Where is Wally?', 'barfoo') as $filename) {
 158              $this->assertFalse(repository::draftfile_exists($draftitemid, '/', $filename));
 159          }
 160      }
 161  
 162      public function test_delete_selected_files() {
 163          global $USER;
 164  
 165          $this->resetAfterTest(true);
 166  
 167          $this->setAdminUser();
 168          $fs = get_file_storage();
 169  
 170          $draftitemid = file_get_unused_draft_itemid();
 171          $context = \context_user::instance($USER->id);
 172  
 173          $dummy = [
 174              'contextid' => $context->id,
 175              'component' => 'user',
 176              'filearea' => 'draft',
 177              'itemid' => $draftitemid,
 178              'filepath' => '/',
 179              'filename' => ''
 180          ];
 181  
 182          // Create some files.
 183          $existingfiles = [
 184              'The Matrix.movie',
 185              'Astalavista.txt',
 186              'foobar',
 187          ];
 188  
 189          $selectedfiles = [
 190              'The Matrix.movie' => [],
 191              'Astalavista.txt' => []
 192          ];
 193          foreach ($existingfiles as $filename) {
 194              $dummy['filename'] = $filename;
 195              $file = $fs->create_file_from_string($dummy, 'Content of ' . $filename);
 196              if (array_key_exists($filename, $selectedfiles)) {
 197                  $selectedfiles[$filename] = (object)[
 198                      'filename' => $filename,
 199                      'filepath' => $file->get_filepath()
 200                  ];
 201              }
 202          }
 203  
 204          // Get area files with default options.
 205          $areafiles = $fs->get_area_files($context->id, 'user', 'draft', $draftitemid);
 206          // Should be the 3 files we added plus the folder.
 207          $this->assertEquals(4, count($areafiles));
 208  
 209          repository_delete_selected_files($context, 'user', 'draft', $draftitemid, $selectedfiles);
 210  
 211          $areafiles = $fs->get_area_files($context->id, 'user', 'draft', $draftitemid);
 212          // Should be the 1 file left plus the folder.
 213          $this->assertEquals(2, count($areafiles));
 214      }
 215  
 216      public function test_can_be_edited_by_user() {
 217          $this->resetAfterTest(true);
 218  
 219          $syscontext = \context_system::instance();
 220          $course = $this->getDataGenerator()->create_course();
 221          $coursecontext = \context_course::instance($course->id);
 222          $roleid = create_role('A role', 'arole', 'A role', '');
 223          $user = $this->getDataGenerator()->create_user();
 224          $this->setUser($user);
 225  
 226          // Instance on a site level.
 227          $this->getDataGenerator()->create_repository_type('flickr_public');
 228          $repoid = $this->getDataGenerator()->create_repository('flickr_public')->id;
 229          $systemrepo = repository::get_repository_by_id($repoid, $syscontext);
 230  
 231          role_assign($roleid, $user->id, $syscontext->id);
 232          assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext, true);
 233          assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
 234          accesslib_clear_all_caches_for_unit_testing();
 235          $this->assertTrue($systemrepo->can_be_edited_by_user());
 236  
 237          assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $syscontext, true);
 238          assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $syscontext, true);
 239          accesslib_clear_all_caches_for_unit_testing();
 240          $this->assertFalse($systemrepo->can_be_edited_by_user());
 241  
 242          assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
 243          assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $syscontext, true);
 244          accesslib_clear_all_caches_for_unit_testing();
 245          $this->assertFalse($systemrepo->can_be_edited_by_user());
 246  
 247          role_unassign($roleid, $user->id, $syscontext->id);
 248          accesslib_clear_all_caches_for_unit_testing();
 249  
 250          // Instance on a course level.
 251          $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleid);
 252  
 253          $params = array('contextid' => $coursecontext->id);
 254          $repoid = $this->getDataGenerator()->create_repository('flickr_public', $params)->id;
 255          $courserepo = repository::get_repository_by_id($repoid, $coursecontext);
 256  
 257          assign_capability('moodle/course:update', CAP_ALLOW, $roleid, $coursecontext, true);
 258          assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $coursecontext, true);
 259          accesslib_clear_all_caches_for_unit_testing();
 260          $this->assertTrue($courserepo->can_be_edited_by_user());
 261  
 262          assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $coursecontext, true);
 263          accesslib_clear_all_caches_for_unit_testing();
 264          $this->assertFalse($courserepo->can_be_edited_by_user());
 265  
 266          assign_capability('moodle/course:update', CAP_ALLOW, $roleid, $coursecontext, true);
 267          assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $coursecontext, true);
 268          accesslib_clear_all_caches_for_unit_testing();
 269          $this->assertFalse($courserepo->can_be_edited_by_user());
 270  
 271          role_unassign($roleid, $user->id, $coursecontext->id);
 272          accesslib_clear_all_caches_for_unit_testing();
 273  
 274          // Instance on a user level.
 275          $otheruser = $this->getDataGenerator()->create_user();
 276          $otherusercontext = \context_user::instance($otheruser->id);
 277          role_assign($roleid, $user->id, $syscontext->id);
 278          assign_capability('repository/flickr_public:view', CAP_ALLOW, $roleid, $syscontext, true);
 279          accesslib_clear_all_caches_for_unit_testing();
 280  
 281          // Editing someone else's instance.
 282          $record = array('contextid' => $otherusercontext->id);
 283          $repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
 284          $userrepo = repository::get_repository_by_id($repoid, $syscontext);
 285          $this->assertFalse($userrepo->can_be_edited_by_user());
 286  
 287          // Editing my own instance.
 288          $usercontext = \context_user::instance($user->id);
 289          $record = array('contextid' => $usercontext->id);
 290          $repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
 291          $userrepo = repository::get_repository_by_id($repoid, $syscontext);
 292          $this->assertTrue($userrepo->can_be_edited_by_user());
 293  
 294      }
 295  
 296      public function test_check_capability() {
 297          $this->resetAfterTest(true);
 298  
 299          $syscontext = \context_system::instance();
 300          $course1 = $this->getDataGenerator()->create_course();
 301          $course1context = \context_course::instance($course1->id);
 302          $course2 = $this->getDataGenerator()->create_course();
 303          $course2context = \context_course::instance($course2->id);
 304  
 305          $forumdata = new \stdClass();
 306          $forumdata->course = $course1->id;
 307          $forumc1 = $this->getDataGenerator()->create_module('forum', $forumdata);
 308          $forumc1context = \context_module::instance($forumc1->cmid);
 309          $forumdata->course = $course2->id;
 310          $forumc2 = $this->getDataGenerator()->create_module('forum', $forumdata);
 311          $forumc2context = \context_module::instance($forumc2->cmid);
 312  
 313          $blockdata = new \stdClass();
 314          $blockdata->parentcontextid = $course1context->id;
 315          $blockc1 = $this->getDataGenerator()->create_block('online_users', $blockdata);
 316          $blockc1context = \context_block::instance($blockc1->id);
 317          $blockdata->parentcontextid = $course2context->id;
 318          $blockc2 = $this->getDataGenerator()->create_block('online_users', $blockdata);
 319          $blockc2context = \context_block::instance($blockc2->id);
 320  
 321          $user1 = $this->getDataGenerator()->create_user();
 322          $user1context = \context_user::instance($user1->id);
 323          $user2 = $this->getDataGenerator()->create_user();
 324          $user2context = \context_user::instance($user2->id);
 325  
 326          // New role prohibiting Flickr Public access.
 327          $roleid = create_role('No Flickr Public', 'noflickrpublic', 'No Flickr Public', '');
 328          assign_capability('repository/flickr_public:view', CAP_PROHIBIT, $roleid, $syscontext, true);
 329  
 330          // Disallow system access to Flickr Public to user 2.
 331          role_assign($roleid, $user2->id, $syscontext->id);
 332          accesslib_clear_all_caches_for_unit_testing();
 333  
 334          // Enable repositories.
 335          $this->getDataGenerator()->create_repository_type('flickr_public');
 336          $this->getDataGenerator()->create_repository_type('dropbox');
 337  
 338          // Instance on a site level.
 339          $repoid = $this->getDataGenerator()->create_repository('flickr_public')->id;
 340          $systemrepo = repository::get_repository_by_id($repoid, $syscontext);
 341  
 342          // Check that everyone with right capability can view a site-wide repository.
 343          $this->setUser($user1);
 344          $this->assertTrue($systemrepo->check_capability());
 345  
 346          // Without the capability, we cannot view a site-wide repository.
 347          $this->setUser($user2);
 348          $caughtexception = false;
 349          try {
 350              $systemrepo->check_capability();
 351          } catch (repository_exception $e) {
 352              $caughtexception = true;
 353          }
 354          $this->assertTrue($caughtexception);
 355  
 356          // Instance on a course level.
 357          $record = new \stdClass();
 358          $record->contextid = $course1context->id;
 359          $courserepoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
 360  
 361          // Within the course, I can view the repository.
 362          $courserepo = repository::get_repository_by_id($courserepoid, $course1context);
 363          $this->setUser($user1);
 364          $this->assertTrue($courserepo->check_capability());
 365          // But not without the capability.
 366          $this->setUser($user2);
 367          $caughtexception = false;
 368          try {
 369              $courserepo->check_capability();
 370          } catch (repository_exception $e) {
 371              $caughtexception = true;
 372          }
 373          $this->assertTrue($caughtexception);
 374  
 375          // From another course I cannot, with or without the capability.
 376          $courserepo = repository::get_repository_by_id($courserepoid, $course2context);
 377          $this->setUser($user1);
 378          $caughtexception = false;
 379          try {
 380              $courserepo->check_capability();
 381          } catch (repository_exception $e) {
 382              $caughtexception = true;
 383          }
 384          $this->assertTrue($caughtexception);
 385          $this->setUser($user2);
 386          $caughtexception = false;
 387          try {
 388              $courserepo->check_capability();
 389          } catch (repository_exception $e) {
 390              $caughtexception = true;
 391          }
 392          $this->assertTrue($caughtexception);
 393  
 394          // From a module within the course, I can view the repository.
 395          $courserepo = repository::get_repository_by_id($courserepoid, $forumc1context);
 396          $this->setUser($user1);
 397          $this->assertTrue($courserepo->check_capability());
 398          // But not without the capability.
 399          $this->setUser($user2);
 400          $caughtexception = false;
 401          try {
 402              $courserepo->check_capability();
 403          } catch (repository_exception $e) {
 404              $caughtexception = true;
 405          }
 406          $this->assertTrue($caughtexception);
 407  
 408          // From a module in the wrong course, I cannot view the repository.
 409          $courserepo = repository::get_repository_by_id($courserepoid, $forumc2context);
 410          $this->setUser($user1);
 411          $caughtexception = false;
 412          try {
 413              $courserepo->check_capability();
 414          } catch (repository_exception $e) {
 415              $caughtexception = true;
 416          }
 417          $this->assertTrue($caughtexception);
 418  
 419          // From a block within the course, I can view the repository.
 420          $courserepo = repository::get_repository_by_id($courserepoid, $blockc1context);
 421          $this->setUser($user1);
 422          $this->assertTrue($courserepo->check_capability());
 423          // But not without the capability.
 424          $this->setUser($user2);
 425          $caughtexception = false;
 426          try {
 427              $courserepo->check_capability();
 428          } catch (repository_exception $e) {
 429              $caughtexception = true;
 430          }
 431          $this->assertTrue($caughtexception);
 432  
 433          // From a block in the wrong course, I cannot view the repository.
 434          $courserepo = repository::get_repository_by_id($courserepoid, $blockc2context);
 435          $this->setUser($user1);
 436          $caughtexception = false;
 437          try {
 438              $courserepo->check_capability();
 439          } catch (repository_exception $e) {
 440              $caughtexception = true;
 441          }
 442          $this->assertTrue($caughtexception);
 443  
 444          // Instance on a user level.
 445          // Instance on a course level.
 446          $record = new \stdClass();
 447          $record->contextid = $user1context->id;
 448          $user1repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
 449          $record->contextid = $user2context->id;
 450          $user2repoid = $this->getDataGenerator()->create_repository('flickr_public', $record)->id;
 451  
 452          // Check that a user can see its own repository.
 453          $userrepo = repository::get_repository_by_id($user1repoid, $syscontext);
 454          $this->setUser($user1);
 455          $this->assertTrue($userrepo->check_capability());
 456          // But not without the capability.
 457          $userrepo = repository::get_repository_by_id($user2repoid, $syscontext);
 458          $this->setUser($user2);
 459          $caughtexception = false;
 460          try {
 461              $userrepo->check_capability();
 462          } catch (repository_exception $e) {
 463              $caughtexception = true;
 464          }
 465          $this->assertTrue($caughtexception);
 466  
 467          // Check that a user cannot see someone's repository.
 468          $userrepo = repository::get_repository_by_id($user2repoid, $syscontext);
 469          $this->setUser($user1);
 470          $caughtexception = false;
 471          try {
 472              $userrepo->check_capability();
 473          } catch (repository_exception $e) {
 474              $caughtexception = true;
 475          }
 476          $this->assertTrue($caughtexception);
 477          // Make sure the repo from user 2 was accessible.
 478          role_unassign($roleid, $user2->id, $syscontext->id);
 479          accesslib_clear_all_caches_for_unit_testing();
 480          $this->setUser($user2);
 481          $this->assertTrue($userrepo->check_capability());
 482          role_assign($roleid, $user2->id, $syscontext->id);
 483          accesslib_clear_all_caches_for_unit_testing();
 484  
 485          // Check that a user can view SOME repositories when logged in as someone else.
 486          $params = new \stdClass();
 487          $params->name = 'Dropbox';
 488          $params->dropbox_issuerid = '2';
 489          $privaterepoid = $this->getDataGenerator()->create_repository('dropbox')->id;
 490          $notprivaterepoid = $this->getDataGenerator()->create_repository('upload')->id;
 491  
 492          $privaterepo = repository::get_repository_by_id($privaterepoid, $syscontext);
 493          $notprivaterepo = repository::get_repository_by_id($notprivaterepoid, $syscontext);
 494          $userrepo = repository::get_repository_by_id($user1repoid, $syscontext);
 495  
 496          $this->setAdminUser();
 497          \core\session\manager::loginas($user1->id, $syscontext);
 498  
 499          // Logged in as, I cannot view a user instance.
 500          $caughtexception = false;
 501          try {
 502              $userrepo->check_capability();
 503          } catch (repository_exception $e) {
 504              $caughtexception = true;
 505          }
 506          $this->assertTrue($caughtexception);
 507  
 508          // Logged in as, I cannot view a private instance.
 509          $caughtexception = false;
 510          try {
 511              $privaterepo->check_capability();
 512          } catch (repository_exception $e) {
 513              $caughtexception = true;
 514          }
 515          $this->assertTrue($caughtexception);
 516  
 517          // Logged in as, I can view a non-private instance.
 518          $this->assertTrue($notprivaterepo->check_capability());
 519      }
 520  
 521      function test_delete_all_for_context() {
 522          global $DB;
 523          $this->resetAfterTest(true);
 524  
 525          $this->setAdminUser();
 526          $course = $this->getDataGenerator()->create_course();
 527          $user = $this->getDataGenerator()->create_user();
 528          $this->getDataGenerator()->create_repository_type('flickr_public');
 529          $this->getDataGenerator()->create_repository_type('filesystem');
 530          $coursecontext = \context_course::instance($course->id);
 531          $usercontext = \context_user::instance($user->id);
 532  
 533          // Creating course instances.
 534          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
 535          $courserepo1 = repository::get_repository_by_id($repo->id, $coursecontext);
 536          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 537  
 538          $repo = $this->getDataGenerator()->create_repository('filesystem', array('contextid' => $coursecontext->id));
 539          $courserepo2 = repository::get_repository_by_id($repo->id, $coursecontext);
 540          $this->assertEquals(2, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 541  
 542          // Creating user instances.
 543          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
 544          $userrepo1 = repository::get_repository_by_id($repo->id, $usercontext);
 545          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 546  
 547          $repo = $this->getDataGenerator()->create_repository('filesystem', array('contextid' => $usercontext->id));
 548          $userrepo2 = repository::get_repository_by_id($repo->id, $usercontext);
 549          $this->assertEquals(2, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 550  
 551          // Simulation of course deletion.
 552          repository::delete_all_for_context($coursecontext->id);
 553          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 554          $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $courserepo1->id)));
 555          $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $courserepo2->id)));
 556          $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $courserepo1->id)));
 557          $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $courserepo2->id)));
 558  
 559          // Simulation of user deletion.
 560          repository::delete_all_for_context($usercontext->id);
 561          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 562          $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $userrepo1->id)));
 563          $this->assertEquals(0, $DB->count_records('repository_instances', array('id' => $userrepo2->id)));
 564          $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $userrepo1->id)));
 565          $this->assertEquals(0, $DB->count_records('repository_instance_config', array('instanceid' => $userrepo2->id)));
 566  
 567          // Checking deletion upon course context deletion.
 568          $course = $this->getDataGenerator()->create_course();
 569          $coursecontext = \context_course::instance($course->id);
 570          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
 571          $courserepo = repository::get_repository_by_id($repo->id, $coursecontext);
 572          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 573          $coursecontext->delete();
 574          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 575  
 576          // Checking deletion upon user context deletion.
 577          $user = $this->getDataGenerator()->create_user();
 578          $usercontext = \context_user::instance($user->id);
 579          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
 580          $userrepo = repository::get_repository_by_id($repo->id, $usercontext);
 581          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 582          $usercontext->delete();
 583          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 584  
 585          // Checking deletion upon course deletion.
 586          $course = $this->getDataGenerator()->create_course();
 587          $coursecontext = \context_course::instance($course->id);
 588          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $coursecontext->id));
 589          $courserepo = repository::get_repository_by_id($repo->id, $coursecontext);
 590          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 591          delete_course($course, false);
 592          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $coursecontext->id)));
 593  
 594          // Checking deletion upon user deletion.
 595          $user = $this->getDataGenerator()->create_user();
 596          $usercontext = \context_user::instance($user->id);
 597          $repo = $this->getDataGenerator()->create_repository('flickr_public', array('contextid' => $usercontext->id));
 598          $userrepo = repository::get_repository_by_id($repo->id, $usercontext);
 599          $this->assertEquals(1, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 600          delete_user($user);
 601          $this->assertEquals(0, $DB->count_records('repository_instances', array('contextid' => $usercontext->id)));
 602      }
 603  
 604      /**
 605       * Create test file in user private files
 606       *
 607       * @param string $filepath file path
 608       * @param string $filename file name
 609       */
 610      private function create_user_private_file(string $filepath, string $filename): void {
 611          global $USER;
 612  
 613          $filerecord = [];
 614          $filerecord['contextid'] = \context_user::instance($USER->id)->id;
 615          $filerecord['component'] = 'user';
 616          $filerecord['filearea'] = 'private';
 617          $filerecord['itemid'] = 0;
 618          $filerecord['filepath'] = $filepath;
 619          $filerecord['filename'] = $filename;
 620          $filerecord['userid'] = $USER->id;
 621  
 622          $fs = get_file_storage();
 623          $fs->create_file_from_string($filerecord, hash("md5", $filepath . $filename));
 624      }
 625  
 626      public function test_listing_and_filter() {
 627          $this->resetAfterTest(true);
 628          $this->setUser($this->getDataGenerator()->create_user());
 629          $repoid = $this->getDataGenerator()->create_repository('user')->id;
 630          $this->create_user_private_file('/', 'image1.jpg');
 631          $this->create_user_private_file('/', 'file1.txt');
 632          $this->create_user_private_file('/folder/', 'image2.jpg');
 633          $this->create_user_private_file('/folder/', 'file2.txt');
 634          $this->create_user_private_file('/ftexts/', 'file3.txt');
 635  
 636          // Listing without filters returns 4 records (2 files and 2 directories).
 637          $repo = repository::get_repository_by_id($repoid, \context_system::instance());
 638          $this->assertCount(4,  $repo->get_listing()['list']);
 639  
 640          // Listing with filters returns 3 records (1 files and 2 directories).
 641          $_POST['accepted_types'] = ['.jpg'];
 642          $this->assertCount(3,  $repo->get_listing()['list']);
 643      }
 644  }