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.
   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  /**
  18   * BBB Library tests class.
  19   *
  20   * @package   mod_bigbluebuttonbn
  21   * @copyright 2018 - present, Blindside Networks Inc
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @author    Laurent David (laurent@call-learning.fr)
  24   */
  25  
  26  namespace mod_bigbluebuttonbn\local\helpers;
  27  
  28  use context_course;
  29  use context_module;
  30  use context_system;
  31  use mod_bigbluebuttonbn\instance;
  32  use mod_bigbluebuttonbn\test\testcase_helper_trait;
  33  use stdClass;
  34  use stored_file;
  35  
  36  /**
  37   * BBB Library tests class.
  38   *
  39   * @package   mod_bigbluebuttonbn
  40   * @copyright 2018 - present, Blindside Networks Inc
  41   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   * @author    Laurent David (laurent@call-learning.fr)
  43   * @covers \mod_bigbluebuttonbn\local\helpers\files
  44   * @coversDefaultClass \mod_bigbluebuttonbn\local\helpers\files
  45   */
  46  class files_test extends \advanced_testcase {
  47      use testcase_helper_trait;
  48  
  49      /** @var string Filename used for the presentation */
  50      const PRESENTATION_FILENAME = 'bbpresentation.pptx';
  51  
  52      /** @var string Filename used for the presentation */
  53      const PRESENTATION_FILEPATH = '/mod/bigbluebuttonbn/tests/fixtures/bbpresentation.pptx';
  54  
  55      /**
  56       * Plugin valid test case
  57       */
  58      public function test_pluginfile_valid() {
  59          $this->resetAfterTest();
  60          $this->assertFalse(files::pluginfile_valid(context_course::instance($this->get_course()->id), 'presentation'));
  61          $this->assertTrue(files::pluginfile_valid(context_system::instance(), 'presentation'));
  62          $this->assertFalse(files::pluginfile_valid(context_system::instance(), 'otherfilearea'));
  63      }
  64  
  65      /**
  66       * Plugin file test case
  67       */
  68      public function test_pluginfile_file() {
  69          global $CFG;
  70          $this->resetAfterTest();
  71  
  72          list($user, $bbactivity) = $this->create_user_and_activity($CFG->dirroot . self::PRESENTATION_FILEPATH);
  73          $this->setUser($user);
  74          $instance = instance::get_from_instanceid($bbactivity->id);
  75          $cm = $instance->get_cm();
  76          $cmrecord = $cm->get_course_module_record();
  77          /** @var stored_file $mediafile */
  78          $mediafile =
  79              files::pluginfile_file($this->get_course(), $cmrecord, $instance->get_context(),
  80                  'presentation', [self::PRESENTATION_FILENAME]);
  81          $this->assertEquals(self::PRESENTATION_FILENAME, $mediafile->get_filename());
  82      }
  83  
  84      /**
  85       * Get presentation file
  86       */
  87      public function test_default_presentation_get_file() {
  88          $this->resetAfterTest();
  89  
  90          list($user, $bbactivity) = $this->create_user_and_activity();
  91          $this->setUser($user);
  92  
  93          $instance = instance::get_from_instanceid($bbactivity->id);
  94          $cm = $instance->get_cm();
  95          $cmrecord = $cm->get_course_module_record();
  96          $mediafilename =
  97              files::get_plugin_filename($this->get_course(), $cmrecord, $instance->get_context(), ['presentation.pptx']);
  98          $this->assertEquals('presentation.pptx', $mediafilename);
  99      }
 100  
 101      /**
 102       * Test that file is accessible only once.
 103       */
 104      public function test_presentation_file_accessible_twice() {
 105          global $CFG;
 106          $this->resetAfterTest();
 107  
 108          list($user, $bbactivity) = $this->create_user_and_activity($CFG->dirroot . self::PRESENTATION_FILEPATH);
 109          $this->setUser($user);
 110          $CFG->bigbluebuttonbn_preuploadpresentation_editable = true;
 111          $instance = instance::get_from_instanceid($bbactivity->id);
 112          $presentation = $instance->get_presentation_for_bigbluebutton_upload();
 113          $fulldirset = explode('/', $presentation['url']);
 114          $filename = array_pop($fulldirset);
 115          $nonce = array_pop($fulldirset);
 116          $cm = $instance->get_cm();
 117          $cmrecord = $cm->get_course_module_record();
 118          // The link should be valid twice.
 119          for ($i = 0; $i < 2; $i++) {
 120              $mediafile = files::pluginfile_file($this->get_course(), $cmrecord, $instance->get_context(), 'presentation',
 121                  [$nonce, $filename]);
 122              $this->assertEquals($filename, $mediafile->get_filename());
 123          }
 124          // Third time is a charm, this should be false.
 125          $mediafile = files::pluginfile_file($this->get_course(), $cmrecord, $instance->get_context(), 'presentation',
 126              [$nonce, $filename]);
 127          $this->assertFalse($mediafile);
 128      }
 129  
 130      /**
 131       * Test that file is accessible only once.
 132       */
 133      public function test_presentation_file_not_accessible_externally() {
 134          global $CFG;
 135          $this->resetAfterTest();
 136  
 137          list($user, $bbactivity) = $this->create_user_and_activity($CFG->dirroot . self::PRESENTATION_FILEPATH);
 138          $this->setUser($user);
 139          $CFG->bigbluebuttonbn_preuploadpresentation_editable = true;
 140          $instance = instance::get_from_instanceid($bbactivity->id);
 141          $presentation = $instance->get_presentation();
 142          $fulldirset = explode('/', $presentation['url']);
 143          $filename = array_pop($fulldirset);
 144          $this->setGuestUser();
 145          $this->expectException(\require_login_exception::class);
 146          $cm = $instance->get_cm();
 147          $cmrecord = $cm->get_course_module_record();
 148          files::pluginfile_file($this->get_course(), $cmrecord, $instance->get_context(), 'presentation', [$filename]);
 149  
 150          $this->setUser($user);
 151          $mediafile = files::pluginfile_file($this->get_course(), $cmrecord, $instance->get_context(), 'presentation', [$filename]);
 152          $this->assertNotNull($mediafile);
 153      }
 154  
 155      /**
 156       * Get filename test
 157       */
 158      public function test_pluginfile_filename() {
 159          global $CFG;
 160          $this->resetAfterTest();
 161  
 162          list($user, $bbactivity, $bbactivitycm, $bbactivitycontext) = $this->create_user_and_activity();
 163          $this->setUser($user);
 164          $this->create_sample_file(self::PRESENTATION_FILENAME, $bbactivitycontext->id);
 165          $CFG->bigbluebuttonbn_preuploadpresentation_editable = true;
 166          $presentationdef = files::get_presentation($bbactivitycontext, self::PRESENTATION_FILENAME, $bbactivity->id, true);
 167          $pathparts = explode('/', $presentationdef['url']);
 168          $filename = array_pop($pathparts);
 169          $salt = array_pop($pathparts);
 170          $filename = files::get_plugin_filename($this->get_course(), $bbactivitycm->get_course_module_record(), $bbactivitycontext,
 171              [$salt, $filename]);
 172          $this->assertEquals(self::PRESENTATION_FILENAME, $filename);
 173      }
 174  
 175      /**
 176       * Get media files
 177       */
 178      public function test_get_media_file() {
 179          $this->resetAfterTest();
 180  
 181          list($user, $bbactivity) = $this->create_user_and_activity();
 182          $this->setUser($user);
 183  
 184          $bbformdata = $this->get_form_data_from_instance($bbactivity);
 185          $mediafilepath = files::save_media_file($bbformdata);
 186          $this->assertEmpty($mediafilepath);
 187  
 188          // From test_delete_original_file_from_draft (lib/test/filelib_test.php)
 189          // Create a bbb private file.
 190          $this->create_sample_file(self::PRESENTATION_FILENAME, context_module::instance($bbformdata->coursemodule)->id);
 191          file_prepare_draft_area($bbformdata->presentation,
 192              context_module::instance($bbformdata->coursemodule)->id,
 193              'mod_bigbluebuttonbn',
 194              'presentation', 0);
 195  
 196          $mediafilepath = files::save_media_file($bbformdata);
 197          $this->assertEquals('/' . self::PRESENTATION_FILENAME, $mediafilepath);
 198      }
 199  
 200      /**
 201       * Create a user and an activity
 202       *
 203       * @param string|null $presentationpath
 204       * @param bool $closed
 205       * @return array
 206       */
 207      protected function create_user_and_activity($presentationpath = null, $closed = false): array {
 208          $generator = $this->getDataGenerator();
 209          $user = $generator->create_user();
 210          $this->setAdminUser();
 211          $activitydata = ['closingtime' => time() + ($closed ? -3600 : +3600)];
 212          if (!empty($presentationpath)) {
 213              $activitydata['presentation'] = $presentationpath;
 214          }
 215          list($bbactivitycontext, $bbactivitycm, $bbactivity) =
 216              $this->create_instance(null, $activitydata);
 217          $generator->enrol_user($user->id, $this->get_course()->id, 'editingteacher');
 218          return [$user, $bbactivity, $bbactivitycm, $bbactivitycontext];
 219      }
 220  
 221      /**
 222       * Helper to create sample file for tests
 223       *
 224       * @param string $filename
 225       * @param int $contextid
 226       * @return stored_file
 227       */
 228      protected function create_sample_file($filename, $contextid) {
 229          $bbbfilerecord = new stdClass;
 230          $bbbfilerecord->contextid = $contextid;
 231          $bbbfilerecord->component = 'mod_bigbluebuttonbn';
 232          $bbbfilerecord->filearea = 'presentation';
 233          $bbbfilerecord->itemid = 0;
 234          $bbbfilerecord->filepath = '/';
 235          $bbbfilerecord->filename = $filename;
 236          $bbbfilerecord->source = 'test';
 237          $fs = get_file_storage();
 238          return $fs->create_file_from_string($bbbfilerecord, 'Presentation file content');
 239      }
 240  }