Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.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  namespace mod_bigbluebuttonbn\local;
  17  
  18  use backup;
  19  use backup_controller;
  20  use mod_bigbluebuttonbn\extension;
  21  use mod_bigbluebuttonbn\instance;
  22  use mod_bigbluebuttonbn\local\extension\mod_instance_helper;
  23  use mod_bigbluebuttonbn\meeting;
  24  use mod_bigbluebuttonbn\test\subplugins_test_helper_trait;
  25  use mod_bigbluebuttonbn\test\testcase_helper_trait;
  26  use restore_controller;
  27  use restore_dbops;
  28  
  29  /**
  30   * Extension helper class test
  31   *
  32   * @package   mod_bigbluebuttonbn
  33   * @copyright 2023 - present, Blindside Networks Inc
  34   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   * @author    Laurent David (laurent@call-learning.fr)
  36   * @coversDefaultClass \mod_bigbluebuttonbn\extension
  37   */
  38  class extension_test extends \advanced_testcase {
  39      use subplugins_test_helper_trait;
  40      use testcase_helper_trait;
  41  
  42      /**
  43       * Setup our fake plugin
  44       *
  45       * @return void
  46       */
  47      public function setUp(): void {
  48          $this->resetAfterTest(true);
  49          $this->setup_fake_plugin('simple');
  50          $this->resetDebugging(); // We might have debugging messages issued from setup_fake_plugin here that we need to get rid of.
  51      }
  52  
  53  
  54      /**
  55       * Setup our fake plugin
  56       *
  57       * @return void
  58       */
  59      public function tearDown(): void {
  60          $this->uninstall_fake_plugin('simple');
  61      }
  62  
  63      /**
  64       * Test for the type_text provider.
  65       *
  66       * @param bool $bbbenabled
  67       * @param string $apiclass
  68       * @param array $extensionclasses
  69       *
  70       * @dataProvider classes_implementing_class
  71       * @covers       \mod_bigbluebuttonbn\extension::get_instances_implementing
  72       */
  73      public function test_get_class_implementing(bool $bbbenabled, string $apiclass, array $extensionclasses): void {
  74          $this->enable_plugins($bbbenabled);
  75          // Make the method public so we can test it.
  76          $reflectionextension = new \ReflectionClass(extension::class);
  77          $getclassimplementing = $reflectionextension->getMethod('get_instances_implementing');
  78          $getclassimplementing->setAccessible(true);
  79          $allfoundinstances = $getclassimplementing->invoke(null, $apiclass);
  80          $foundclasses = array_map(
  81              function($instance) {
  82                  return get_class($instance);
  83              },
  84              $allfoundinstances
  85          );
  86          $this->assertEquals($extensionclasses, $foundclasses);
  87      }
  88  
  89      /**
  90       * Test the add module callback
  91       *
  92       * @return void
  93       * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
  94       */
  95      public function test_mod_instance_helper_add() {
  96          global $DB;
  97          // Enable plugin.
  98          $this->enable_plugins(true);
  99  
 100          $course = $this->getDataGenerator()->create_course();
 101          $record = $this->getDataGenerator()->create_module(
 102              'bigbluebuttonbn',
 103              ['course' => $course->id, 'newfield' => 2]
 104          );
 105          $this->assertEquals(2, $DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
 106      }
 107  
 108      /**
 109       * Test the update module callback
 110       *
 111       * @return void
 112       * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
 113       */
 114      public function test_mod_instance_helper_update() {
 115          global $DB;
 116          $this->setAdminUser();
 117          // Enable plugin.
 118          $this->enable_plugins(true);
 119  
 120          $course = $this->getDataGenerator()->create_course();
 121          $record = $this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course->id, 'newfield' => 2]);
 122          $cm = get_fast_modinfo($course)->instances['bigbluebuttonbn'][$record->id];
 123          [$cm, $context, $moduleinfo, $data] = get_moduleinfo_data($cm, $course);
 124          $data->newfield = 3;
 125          bigbluebuttonbn_update_instance($data);
 126          $this->assertEquals(3, $DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
 127      }
 128  
 129      /**
 130       * Test delete module callback
 131       *
 132       * @return void
 133       * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
 134       */
 135      public function test_mod_instance_helper_delete() {
 136          global $DB;
 137          $this->initialise_mock_server();
 138          // Enable plugin.
 139          $this->enable_plugins(true);
 140  
 141          $course = $this->getDataGenerator()->create_course();
 142          $record = $this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course->id, 'newfield' => 2]);
 143          $cm = get_fast_modinfo($course)->instances['bigbluebuttonbn'][$record->id];
 144          course_delete_module($cm->id, false);
 145          $this->assertFalse($DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
 146      }
 147  
 148      /**
 149       * Test the action_url_addons with plugin enabled
 150       *
 151       * @return void
 152       * @covers \mod_bigbluebuttonbn\extension::action_url_addons
 153       */
 154      public function test_action_url_addons() {
 155          // Enable plugin.
 156          $this->enable_plugins(true);
 157          $course = $this->get_course();
 158          [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
 159          $bbactivity->newfield = 4;
 160          extension::update_instance($bbactivity);
 161          ['data' => $additionalvar1, 'metadata' => $additionalvar2] =
 162              extension::action_url_addons('create', [], ['bbb-meta' => 'Test'], $bbactivity->id);
 163          $this->assertEmpty($additionalvar1);
 164          $this->assertCount(2, $additionalvar2);
 165          $this->assertEquals($additionalvar2['newfield'], 4);
 166          ['data' => $additionalvar1, 'metadata' => $additionalvar2] = extension::action_url_addons('delete');
 167          $this->assertEmpty($additionalvar1);
 168          $this->assertEmpty($additionalvar2);
 169      }
 170  
 171      /**
 172       * Test the action_url_addons with plugin enabled
 173       *
 174       * @return void
 175       * @covers \mod_bigbluebuttonbn\extension::action_url_addons
 176       */
 177      public function test_join_url_with_additional_field() {
 178          $this->initialise_mock_server();
 179          // Enable plugin.
 180          $this->enable_plugins(true);
 181          $course = $this->get_course();
 182          [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
 183          $bbactivity->newfield = 4;
 184          extension::update_instance($bbactivity);
 185          $instance = instance::get_from_instanceid($bbactivity->id);
 186          $meeting = new meeting($instance);
 187          $meetingjoinurl = $meeting->get_join_url();
 188          $this->assertStringContainsString('newfield=4', $meetingjoinurl);
 189      }
 190  
 191      /**
 192       * Test backup restore (with extension)
 193       *
 194       * @covers       \backup_bigbluebuttonbn_activity_task
 195       */
 196      public function test_backup_restore(): void {
 197          global $DB, $CFG, $USER;
 198          require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
 199          require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
 200          $this->resetAfterTest();
 201          $course = $this->get_course();
 202          [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
 203          $bbactivity->newfield = 4;
 204          extension::update_instance($bbactivity);
 205  
 206          $this->setAdminUser();
 207  
 208          $CFG->backup_file_logger_level = backup::LOG_NONE;
 209  
 210          // Do backup with default settings.
 211          set_config('backup_general_users', 1, 'backup');
 212          $bc = new backup_controller(backup::TYPE_1COURSE, $course->id,
 213              backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL,
 214              $USER->id);
 215          $bc->execute_plan();
 216          $results = $bc->get_results();
 217          $file = $results['backup_destination'];
 218          $fp = get_file_packer('application/vnd.moodle.backup');
 219          $filepath = $CFG->dataroot . '/temp/backup/test-restore-course';
 220          $file->extract_to_pathname($fp, $filepath);
 221          $bc->destroy();
 222  
 223          // Do restore to new course with default settings.
 224          $newcourseid = restore_dbops::create_new_course(
 225              $course->fullname, $course->shortname . '_2', $course->category);
 226          $rc = new restore_controller('test-restore-course', $newcourseid,
 227              backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id,
 228              backup::TARGET_NEW_COURSE);
 229          $rc->execute_precheck();
 230          $rc->execute_plan();
 231          $rc->destroy();
 232          $cms = get_fast_modinfo($newcourseid)->get_cms();
 233          $newmoduleid = null;
 234          foreach ($cms as $id => $cm) {
 235              if ($cm->modname == 'bigbluebuttonbn') {
 236                  $newmoduleid = $cm->instance;
 237              }
 238          }
 239          // Check instance has been copied.
 240          $this->assertNotNull($newmoduleid);
 241  
 242          // Change the original instance value (this makes sure we are not looking at the same value in the
 243          // original and copy).
 244          $bbactivity->newfield = 5;
 245          extension::update_instance($bbactivity);
 246  
 247          // Now check the copied instance.
 248          $newfieldrecord = $DB->get_record('bbbext_simple', [
 249              'bigbluebuttonbnid' => $newmoduleid,
 250          ]);
 251          $this->assertNotNull($newfieldrecord);
 252          $this->assertEquals(4, $newfieldrecord->newfield);
 253          // And the original.
 254          $oldfieldrecord = $DB->get_record('bbbext_simple', [
 255              'bigbluebuttonbnid' => $bbactivity->id,
 256          ]);
 257          $this->assertNotNull($oldfieldrecord);
 258          $this->assertEquals(5, $oldfieldrecord->newfield);
 259      }
 260  
 261      /**
 262       * Data provider for testing get_class_implementing
 263       *
 264       * @return array[]
 265       */
 266      public function classes_implementing_class(): array {
 267          return [
 268              'mod_instance_helper with plugin disabled' => [
 269                  'bbbenabled' => false,
 270                  'apiclass' => mod_instance_helper::class,
 271                  'result' => []
 272              ],
 273              'mod_instance_helper with plugin enabled' => [
 274                  'bbbenabled' => true,
 275                  'apiclass' => mod_instance_helper::class,
 276                  'result' => [
 277                      'bbbext_simple\\bigbluebuttonbn\\mod_instance_helper'
 278                  ]
 279              ]
 280          ];
 281      }
 282  
 283      /**
 284       * Enable plugins
 285       *
 286       * @param bool $bbbenabled
 287       * @return void
 288       */
 289      private function enable_plugins(bool $bbbenabled) {
 290          // First make sure that either BBB is enabled or not.
 291          set_config('bigbluebuttonbn_default_dpa_accepted', $bbbenabled);
 292          \core\plugininfo\mod::enable_plugin('bigbluebuttonbn', $bbbenabled ? 1 : 0);
 293          $plugin = extension::BBB_EXTENSION_PLUGIN_NAME . '_simple';
 294          if ($bbbenabled) {
 295              unset_config('disabled', $plugin);
 296          } else {
 297              set_config('disabled', 'disabled', $plugin);
 298          }
 299      }
 300  }