Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   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;
  27  
  28  use calendar_event;
  29  use context_module;
  30  use mod_bigbluebuttonbn\test\testcase_helper_trait;
  31  use mod_bigbluebuttonbn_mod_form;
  32  use MoodleQuickForm;
  33  use navigation_node;
  34  use ReflectionClass;
  35  use stdClass;
  36  
  37  defined('MOODLE_INTERNAL') || die();
  38  global $CFG;
  39  require_once($CFG->dirroot . '/mod/bigbluebuttonbn/lib.php');
  40  
  41  /**
  42   * BBB Library tests class.
  43   *
  44   * @package   mod_bigbluebuttonbn
  45   * @copyright 2018 - present, Blindside Networks Inc
  46   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  47   * @author    Laurent David (laurent@call-learning.fr)
  48   */
  49  class lib_test extends \advanced_testcase {
  50      use testcase_helper_trait;
  51  
  52      /**
  53       * Check support
  54       *
  55       * @covers ::bigbluebuttonbn_supports
  56       */
  57      public function test_bigbluebuttonbn_supports() {
  58          $this->resetAfterTest();
  59          $this->assertTrue(bigbluebuttonbn_supports(FEATURE_IDNUMBER));
  60          $this->assertTrue(bigbluebuttonbn_supports(FEATURE_MOD_INTRO));
  61          $this->assertFalse(bigbluebuttonbn_supports(FEATURE_GRADE_HAS_GRADE));
  62      }
  63  
  64      /**
  65       * Check add instance
  66       *
  67       * @covers ::bigbluebuttonbn_add_instance
  68       */
  69      public function test_bigbluebuttonbn_add_instance() {
  70          $this->resetAfterTest();
  71          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
  72          $bbformdata = $this->get_form_data_from_instance($bbactivity);
  73          $id = bigbluebuttonbn_add_instance($bbformdata);
  74          $this->assertNotNull($id);
  75      }
  76  
  77      /**
  78       * Check update instance
  79       *
  80       * @covers ::bigbluebuttonbn_update_instance
  81       */
  82      public function test_bigbluebuttonbn_update_instance() {
  83          $this->resetAfterTest();
  84          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
  85          $bbformdata = $this->get_form_data_from_instance($bbactivity);
  86          $result = bigbluebuttonbn_update_instance($bbformdata);
  87          $this->assertTrue($result);
  88      }
  89  
  90      /**
  91       * Check delete instance
  92       *
  93       * @covers ::bigbluebuttonbn_delete_instance
  94       */
  95      public function test_bigbluebuttonbn_delete_instance() {
  96          $this->resetAfterTest();
  97          $this->initialise_mock_server();
  98          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
  99          $result = bigbluebuttonbn_delete_instance($bbactivity->id);
 100          $this->assertTrue($result);
 101      }
 102  
 103      /**
 104       * Check user outline page
 105       *
 106       * @covers ::bigbluebuttonbn_user_outline
 107       */
 108      public function test_bigbluebuttonbn_user_outline() {
 109          $this->resetAfterTest();
 110  
 111          $generator = $this->getDataGenerator();
 112          $user = $generator->create_user();
 113          $this->setUser($user);
 114  
 115          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance($this->get_course(),
 116              ['completion' => 2, 'completionview' => 1]);
 117          $result = bigbluebuttonbn_user_outline($this->get_course(), $user, $bbactivitycm, $bbactivity);
 118          $this->assertEquals((object) ['info' => '', 'time' => 0], $result);
 119  
 120          bigbluebuttonbn_view($bbactivity, $this->get_course(), $bbactivitycm, $bbactivitycontext);
 121          $result = bigbluebuttonbn_user_outline($this->get_course(), $user, $bbactivitycm, $bbactivity);
 122          $this->assertStringContainsString(get_string('report_room_view', 'mod_bigbluebuttonbn'), $result->info);
 123      }
 124  
 125      /**
 126       * Check user completion
 127       *
 128       * @covers ::bigbluebuttonbn_user_complete
 129       */
 130      public function test_bigbluebuttonbn_user_complete() {
 131          $this->initialise_mock_server();
 132          $this->resetAfterTest();
 133  
 134          $generator = $this->getDataGenerator();
 135          $user = $generator->create_and_enrol($this->get_course());
 136          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance($this->get_course(),
 137              ['completion' => 2, 'completionview' => 1]);
 138          $this->setUser($user);
 139  
 140          // Now create a couple of logs.
 141          bigbluebuttonbn_view($bbactivity, $this->get_course(), $bbactivitycm, $bbactivitycontext);
 142          ob_start();
 143          bigbluebuttonbn_user_complete($this->get_course(), $user, $bbactivitycm, $bbactivity);
 144          $output = ob_get_contents();
 145          ob_end_clean();
 146          $this->assertStringContainsString(get_string('report_room_view', 'mod_bigbluebuttonbn'), $output);
 147      }
 148  
 149      /**
 150       * Check get recent activity
 151       *
 152       * @covers ::bigbluebuttonbn_get_recent_mod_activity
 153       */
 154      public function test_bigbluebuttonbn_get_recent_mod_activity() {
 155          $this->initialise_mock_server();
 156          $this->resetAfterTest();
 157  
 158          $generator = $this->getDataGenerator();
 159          $user = $generator->create_and_enrol($this->get_course());
 160          $this->setUser($user);
 161          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 162          // Now create a couple of logs.
 163          $instance = instance::get_from_instanceid($bbactivity->id);
 164          $recordings = $this->create_recordings_for_instance($instance, [['name' => "Pre-Recording 1"]]);
 165          logger::log_meeting_joined_event($instance, 0);
 166          logger::log_meeting_joined_event($instance, 0);
 167          logger::log_recording_played_event($instance, $recordings[0]->id);
 168  
 169          $activities = $this->prepare_for_recent_activity_array(0, $user->id, 0);
 170          $this->assertCount(4, $activities);
 171          $this->assertEquals(
 172              ["Meeting joined", "Meeting joined", "Recording viewed"],
 173              array_values(
 174                  array_filter(
 175                      array_map(function($activity) {
 176                          return $activity->eventname ?? "";
 177                      }, $activities),
 178                      function($e) {
 179                          return !empty($e);
 180                      }
 181                  )
 182              )
 183          );
 184          $this->assertEquals("Pre-Recording 1", $activities[3]->content); // The recording view event should contain the name
 185          // of the activity.
 186      }
 187  
 188      /**
 189       * Prepare the list of activities as is done in course recent activity
 190       *
 191       * @param int $date
 192       * @param int $user
 193       * @param int $group
 194       * @return array|void
 195       */
 196      protected function prepare_for_recent_activity_array($date, $user, $group) {
 197          // Same algorithm as in cource/recent.php, but stops at the first bbb activity.
 198          $course = $this->get_course();
 199          $modinfo = get_fast_modinfo($course->id);
 200          $sections = array();
 201          $index = 0;
 202          foreach ($modinfo->get_section_info_all() as $i => $section) {
 203              if (!empty($section->uservisible)) {
 204                  $sections[$i] = $section;
 205              }
 206          }
 207          foreach ($sections as $sectionnum => $section) {
 208  
 209              $activity = new stdClass();
 210              $activity->type = 'section';
 211              if ($section->section > 0) {
 212                  $activity->name = get_section_name($this->get_course(), $section);
 213              } else {
 214                  $activity->name = '';
 215              }
 216  
 217              $activity->visible = $section->visible;
 218              $activities[$index++] = $activity;
 219  
 220              if (empty($modinfo->sections[$sectionnum])) {
 221                  continue;
 222              }
 223  
 224              foreach ($modinfo->sections[$sectionnum] as $cmid) {
 225                  $cm = $modinfo->cms[$cmid];
 226  
 227                  if (!$cm->uservisible) {
 228                      continue;
 229                  }
 230  
 231                  if (!empty($filter) && $cm->modname != $filter) {
 232                      continue;
 233                  }
 234  
 235                  if (!empty($filtermodid) && $cmid != $filtermodid) {
 236                      continue;
 237                  }
 238  
 239                  if ($cm->modname == 'bigbluebuttonbn') {
 240                      return bigbluebuttonbn_get_recent_mod_activity($activities,
 241                          $index,
 242                          $date,
 243                          $course->id, $cmid,
 244                          $user,
 245                          $group);
 246                  }
 247              }
 248          }
 249  
 250      }
 251  
 252      /**
 253       * Check user recent activity
 254       *
 255       * @covers ::bigbluebuttonbn_print_recent_mod_activity
 256       */
 257      public function test_bigbluebuttonbn_print_recent_mod_activity() {
 258          $this->initialise_mock_server();
 259          $this->resetAfterTest();
 260  
 261          $generator = $this->getDataGenerator();
 262          $user = $generator->create_and_enrol($this->get_course());
 263          $this->setUser($user);
 264          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 265          // Now create a couple of logs.
 266          $instance = instance::get_from_instanceid($bbactivity->id);
 267          $recordings = $this->create_recordings_for_instance($instance, [['name' => "Pre-Recording 1"]]);
 268          logger::log_meeting_joined_event($instance, 0);
 269          logger::log_meeting_joined_event($instance, 0);
 270          logger::log_recording_played_event($instance, $recordings[0]->id);
 271  
 272          $activities = $this->prepare_for_recent_activity_array(0, $user->id, 0);
 273          ob_start();
 274          bigbluebuttonbn_print_recent_mod_activity($activities[1], $this->get_course()->id, false, [], false);
 275          $output = ob_get_contents();
 276          ob_end_clean();
 277          $this->assertStringContainsString('Meeting joined', $output);
 278      }
 279  
 280  
 281      /**
 282       * Check recent activity for the course
 283       *
 284       * @covers ::bigbluebuttonbn_print_recent_activity
 285       */
 286      public function test_bigbluebuttonbn_print_recent_activity() {
 287          global $CFG;
 288          $this->initialise_mock_server();
 289          $this->resetAfterTest();
 290  
 291          $generator = $this->getDataGenerator();
 292          $user = $generator->create_and_enrol($this->get_course());
 293          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 294          // Now create a couple of logs.
 295          $timestart = time() - HOURSECS;
 296          $instance = instance::get_from_instanceid($bbactivity->id);
 297          $recordings = $this->create_recordings_for_instance($instance, [['name' => "Pre-Recording 1"]]);
 298  
 299          $this->setUser($user); // Important so the logs are set to this user.
 300          logger::log_meeting_joined_event($instance, 0);
 301          logger::log_meeting_joined_event($instance, 0);
 302          logger::log_recording_played_event($instance, $recordings[0]->id);
 303  
 304          $this->setAdminUser();
 305          // Test that everything is displayed.
 306          ob_start();
 307          bigbluebuttonbn_print_recent_activity($this->get_course(), true, $timestart);
 308          $output = ob_get_contents();
 309          ob_end_clean();
 310          $this->assertStringContainsString('Meeting joined', $output);
 311          $this->assertStringContainsString(fullname($user), $output);
 312          // Test that username are displayed in a different format.
 313          $CFG->alternativefullnameformat = 'firstname lastname firstnamephonetic lastnamephonetic middlename alternatename';
 314          $expectedname = "$user->firstname $user->lastname $user->firstnamephonetic "
 315              . "$user->lastnamephonetic $user->middlename $user->alternatename";
 316          ob_start();
 317          bigbluebuttonbn_print_recent_activity($this->get_course(), false, $timestart);
 318          $output = ob_get_contents();
 319          ob_end_clean();
 320          $this->assertStringContainsString('Meeting joined', $output);
 321          $this->assertStringNotContainsString($expectedname, $output);
 322          // Test that nothing is displayed as per timestart.
 323          ob_start();
 324          bigbluebuttonbn_print_recent_activity($this->get_course(), true, time());
 325          $output = ob_get_contents();
 326          ob_end_clean();
 327          $this->assertEmpty($output);
 328      }
 329  
 330      /**
 331       * Check extra capabilities return value
 332       *
 333       * @covers ::bigbluebuttonbn_get_extra_capabilities
 334       */
 335      public function test_bigbluebuttonbn_get_extra_capabilities() {
 336          $this->resetAfterTest();
 337          $this->assertEquals(['moodle/site:accessallgroups'], bigbluebuttonbn_get_extra_capabilities());
 338      }
 339  
 340      /**
 341       * Check form definition
 342       *
 343       * @covers ::bigbluebuttonbn_reset_course_form_definition
 344       */
 345      public function test_bigbluebuttonbn_reset_course_form_definition() {
 346          global $CFG, $PAGE;
 347          $this->initialise_mock_server();
 348  
 349          $PAGE->set_course($this->get_course());
 350          $this->setAdminUser();
 351          $this->resetAfterTest();
 352          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 353          include_once($CFG->dirroot . '/mod/bigbluebuttonbn/mod_form.php');
 354          $data = new stdClass();
 355          $data->instance = $bbactivity;
 356          $data->id = $bbactivity->id;
 357          $data->course = $bbactivity->course;
 358  
 359          $form = new mod_bigbluebuttonbn_mod_form($data, 1, $bbactivitycm, $this->get_course());
 360          $refclass = new ReflectionClass("mod_bigbluebuttonbn_mod_form");
 361          $formprop = $refclass->getProperty('_form');
 362          $formprop->setAccessible(true);
 363  
 364          /* @var $mform MoodleQuickForm quickform object definition */
 365          $mform = $formprop->getValue($form);
 366          bigbluebuttonbn_reset_course_form_definition($mform);
 367          $this->assertNotNull($mform->getElement('bigbluebuttonbnheader'));
 368      }
 369  
 370      /**
 371       * Check defaults for form
 372       *
 373       * @covers ::bigbluebuttonbn_reset_course_form_defaults
 374       */
 375      public function test_bigbluebuttonbn_reset_course_form_defaults() {
 376          global $CFG;
 377          $this->resetAfterTest();
 378          $results = bigbluebuttonbn_reset_course_form_defaults($this->get_course());
 379          $this->assertEquals([
 380              'reset_bigbluebuttonbn_events' => 0,
 381              'reset_bigbluebuttonbn_tags' => 0,
 382              'reset_bigbluebuttonbn_logs' => 0,
 383              'reset_bigbluebuttonbn_recordings' => 0,
 384          ], $results);
 385      }
 386  
 387      /**
 388       * Reset user data
 389       *
 390       * @covers ::bigbluebuttonbn_reset_userdata
 391       */
 392      public function test_bigbluebuttonbn_reset_userdata() {
 393          global $DB;
 394          $this->resetAfterTest();
 395          $data = new stdClass();
 396          $user = $this->getDataGenerator()->create_user();
 397  
 398          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 399          $this->getDataGenerator()->enrol_user($user->id, $this->course->id);
 400          $this->setUser($user);
 401  
 402          logger::log_meeting_joined_event(instance::get_from_instanceid($bbactivity->id), 0);
 403          $data->courseid = $this->get_course()->id;
 404          $data->reset_bigbluebuttonbn_tags = true;
 405          $data->reset_bigbluebuttonbn_logs = true;
 406          $data->course = $bbactivity->course;
 407          // Add and Join.
 408          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 409          $results = bigbluebuttonbn_reset_userdata($data);
 410          $this->assertCount(0, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 411          $this->assertEquals([
 412              'component' => 'BigBlueButton',
 413              'item' => 'Deleted tags',
 414              'error' => false
 415          ],
 416              $results[0]
 417          );
 418      }
 419  
 420      /**
 421       * Reset user data in a course and checks it does not delete logs elsewhere
 422       *
 423       * @covers ::bigbluebuttonbn_reset_userdata
 424       */
 425      public function test_bigbluebuttonbn_reset_userdata_in_a_course() {
 426          global $DB;
 427          $this->resetAfterTest();
 428          $data = new stdClass();
 429          $user = $this->getDataGenerator()->create_user();
 430  
 431          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 432          $this->getDataGenerator()->enrol_user($user->id, $this->course->id);
 433          logger::log_meeting_joined_event(instance::get_from_instanceid($bbactivity->id), 0);
 434  
 435          // Now create another activity in a course and add a couple of logs.
 436          // Aim is to make sure that only logs from one course are deleted.
 437          $course1 = $this->getDataGenerator()->create_course();
 438          list($bbactivitycontext1, $bbactivitycm1, $bbactivity1) = $this->create_instance($course1);
 439          logger::log_meeting_joined_event(instance::get_from_instanceid($bbactivity1->id), 0);
 440  
 441          $data->courseid = $this->get_course()->id;
 442          $data->reset_bigbluebuttonbn_tags = true;
 443          $data->reset_bigbluebuttonbn_logs = true;
 444          $data->course = $bbactivity->course;
 445          // Add and Join.
 446          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 447          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity1->id]));
 448          bigbluebuttonbn_reset_userdata($data);
 449          $this->assertCount(0, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 450          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity1->id]));
 451      }
 452  
 453      /**
 454       * Reset user data in a course but do not delete logs
 455       *
 456       * @covers ::bigbluebuttonbn_reset_userdata
 457       */
 458      public function test_bigbluebuttonbn_reset_userdata_logs_not_deleted() {
 459          global $DB;
 460          $this->resetAfterTest();
 461          $data = new stdClass();
 462          $user = $this->getDataGenerator()->create_user();
 463  
 464          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 465          $this->getDataGenerator()->enrol_user($user->id, $this->course->id);
 466          $this->setUser($user);
 467          logger::log_meeting_joined_event(instance::get_from_instanceid($bbactivity->id), 0);
 468  
 469          $data->courseid = $this->get_course()->id;
 470          $data->reset_bigbluebuttonbn_logs = false;
 471          $data->course = $bbactivity->course;
 472          // Add and Join.
 473          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 474          bigbluebuttonbn_reset_userdata($data);
 475          $this->assertCount(2, $DB->get_records('bigbluebuttonbn_logs', ['bigbluebuttonbnid' => $bbactivity->id]));
 476      }
 477  
 478      /**
 479       * Check course module
 480       *
 481       * @covers ::bigbluebuttonbn_get_coursemodule_info
 482       */
 483      public function test_bigbluebuttonbn_get_coursemodule_info() {
 484          $this->resetAfterTest();
 485          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 486          $info = bigbluebuttonbn_get_coursemodule_info($bbactivitycm);
 487          $this->assertEquals($info->name, $bbactivity->name);
 488      }
 489  
 490      /**
 491       * Check update since
 492       *
 493       * @covers ::bigbluebuttonbn_check_updates_since
 494       */
 495      public function test_bigbluebuttonbn_check_updates_since() {
 496          $this->resetAfterTest();
 497          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 498          $result = bigbluebuttonbn_check_updates_since($bbactivitycm, 0);
 499          $this->assertEquals(
 500              '{"configuration":{"updated":false},"contentfiles":{"updated":false},"introfiles":' .
 501              '{"updated":false},"completion":{"updated":false}}',
 502              json_encode($result)
 503          );
 504      }
 505  
 506      /**
 507       * Check event action (calendar)
 508       *
 509       * @covers ::mod_bigbluebuttonbn_core_calendar_provide_event_action
 510       */
 511      public function test_mod_bigbluebuttonbn_core_calendar_provide_event_action() {
 512          global $DB;
 513          $this->initialise_mock_server();
 514          $this->resetAfterTest();
 515          $this->setAdminUser();
 516          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 517  
 518          // Standard use case, the meeting start and we want add an action event to join the meeting.
 519          $event = $this->create_action_event($this->get_course(), $bbactivity, logger::EVENT_MEETING_START);
 520          $factory = new \core_calendar\action_factory();
 521          $actionevent = mod_bigbluebuttonbn_core_calendar_provide_event_action($event, $factory);
 522          $this->assertEquals("Join session", $actionevent->get_name());
 523  
 524          // User has already joined the meeting (there is log event EVENT_JOIN already for this user).
 525          $instance = instance::get_from_instanceid($bbactivity->id);
 526          logger::log_meeting_joined_event($instance, 0);
 527  
 528          $bbactivity->closingtime = time() - 1000;
 529          $bbactivity->openingtime = time() - 2000;
 530          $DB->update_record('bigbluebuttonbn', $bbactivity);
 531          $event = $this->create_action_event($this->get_course(), $bbactivity, logger::EVENT_MEETING_START);
 532          $actionevent = mod_bigbluebuttonbn_core_calendar_provide_event_action($event, $factory);
 533          $this->assertNull($actionevent);
 534      }
 535  
 536      /**
 537       * Creates an action event.
 538       *
 539       * @param stdClass $course The course the bigbluebutton activity is in
 540       * @param stdClass $bbbactivity The bigbluebutton activity to create an event for
 541       * @param string $eventtype The event type. eg. ASSIGN_EVENT_TYPE_DUE.
 542       * @return bool|calendar_event
 543       */
 544      private function create_action_event(stdClass $course, stdClass $bbbactivity, string $eventtype) {
 545          $event = new stdClass();
 546          $event->name = 'Calendar event';
 547          $event->modulename = 'bigbluebuttonbn';
 548          $event->courseid = $course->id;
 549          $event->instance = $bbbactivity->id;
 550          $event->type = CALENDAR_EVENT_TYPE_ACTION;
 551          $event->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY;
 552          $event->eventtype = $eventtype;
 553          $event->timestart = time();
 554  
 555          return calendar_event::create($event);
 556      }
 557  
 558      /**
 559       * Test setting navigation admin menu
 560       *
 561       * @covers ::bigbluebuttonbn_extend_settings_navigation
 562       */
 563      public function test_bigbluebuttonbn_extend_settings_navigation_admin() {
 564          global $PAGE, $CFG;
 565          $this->resetAfterTest();
 566          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 567          $CFG->bigbluebuttonbn_meetingevents_enabled = true;
 568  
 569          $PAGE->set_cm($bbactivitycm);
 570          $PAGE->set_context(context_module::instance($bbactivitycm->id));
 571          $PAGE->set_url('/mod/bigbluebuttonbn/view.php', ['id' => $bbactivitycm->id]);
 572          $settingnav = $PAGE->settingsnav;
 573  
 574          $this->setAdminUser();
 575          $node = navigation_node::create('testnavigationnode');
 576          bigbluebuttonbn_extend_settings_navigation($settingnav, $node);
 577          $this->assertCount(1, $node->get_children_key_list());
 578      }
 579  
 580      /**
 581       * Check additional setting menu
 582       *
 583       * @covers ::bigbluebuttonbn_extend_settings_navigation
 584       */
 585      public function test_bigbluebuttonbn_extend_settings_navigation_user() {
 586          global $PAGE, $CFG;
 587          $this->resetAfterTest();
 588  
 589          $generator = $this->getDataGenerator();
 590          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 591          $user = $generator->create_user();
 592          $this->setUser($user);
 593          list($course, $bbactivitycmuser) = get_course_and_cm_from_instance($bbactivity->id, 'bigbluebuttonbn');
 594  
 595          $CFG->bigbluebuttonbn_meetingevents_enabled = true;
 596  
 597          $PAGE->set_cm($bbactivitycmuser);
 598          $PAGE->set_context(context_module::instance($bbactivitycm->id));
 599          $PAGE->set_url('/mod/bigbluebuttonbn/view.php', ['id' => $bbactivitycm->id]);
 600  
 601          $settingnav = $PAGE->settingsnav;
 602          $node = navigation_node::create('testnavigationnode');
 603          bigbluebuttonbn_extend_settings_navigation($settingnav, $node);
 604          $this->assertCount(0, $node->get_children_key_list());
 605      }
 606  
 607      /**
 608       * Check the visibility on calendar
 609       * @covers ::mod_bigbluebuttonbn_core_calendar_is_event_visible
 610       */
 611      public function test_mod_bigbluebuttonbn_core_calendar_is_event_visible() {
 612          global $DB;
 613          $this->resetAfterTest();
 614          $this->setAdminUser();
 615          list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance();
 616          $bbactivity->closingtime = time() - 1000;
 617          $bbactivity->openingtime = time() - 2000;
 618          $DB->update_record('bigbluebuttonbn', $bbactivity);
 619          $event = $this->create_action_event($this->get_course(), $bbactivity, logger::EVENT_MEETING_START);
 620          $this->assertFalse(mod_bigbluebuttonbn_core_calendar_is_event_visible($event));
 621          $bbactivity->closingtime = time() + 1000;
 622          $DB->update_record('bigbluebuttonbn', $bbactivity);
 623          $event = $this->create_action_event($this->get_course(), $bbactivity, logger::EVENT_MEETING_START);
 624          $this->assertTrue(mod_bigbluebuttonbn_core_calendar_is_event_visible($event));
 625          $event->instance = 0;
 626          $this->assertFalse(mod_bigbluebuttonbn_core_calendar_is_event_visible($event));
 627      }
 628  
 629      /**
 630       * Check the bigbluebuttonbn_pre_enable_plugin_actions function.
 631       *
 632       * @covers ::bigbluebuttonbn_pre_enable_plugin_actions
 633       * @dataProvider bigbluebuttonbn_pre_enable_plugin_actions_provider
 634       * @param bool $initialstate
 635       * @param bool $expected
 636       * @param int $notificationcount
 637       */
 638      public function test_bigbluebuttonbn_pre_enable_plugin_actions(
 639          ?bool $initialstate,
 640          bool $expected,
 641          int $notificationcount
 642      ): void {
 643          $this->resetAfterTest(true);
 644  
 645          set_config('bigbluebuttonbn_default_dpa_accepted', $initialstate);
 646  
 647          $this->assertEquals($expected, bigbluebuttonbn_pre_enable_plugin_actions());
 648          $this->assertCount($notificationcount, \core\notification::fetch());
 649      }
 650  
 651      /**
 652       * Check the bigbluebuttonbn_pre_enable_plugin_actions function.
 653       *
 654       * @covers ::bigbluebuttonbn_pre_enable_plugin_actions
 655       * @dataProvider bigbluebuttonbn_pre_enable_plugin_actions_provider
 656       * @param bool $initialstate
 657       * @param bool $expected
 658       * @param int $notificationcount
 659       */
 660      public function test_enable_plugin(
 661          ?bool $initialstate,
 662          bool $expected,
 663          int $notificationcount
 664      ): void {
 665          $this->resetAfterTest(true);
 666  
 667          set_config('bigbluebuttonbn_default_dpa_accepted', $initialstate);
 668          $this->assertEquals($expected, \core\plugininfo\mod::enable_plugin('bigbluebuttonbn', 1));
 669          $this->assertCount($notificationcount, \core\notification::fetch());
 670      }
 671  
 672      /**
 673       * Data provider for bigbluebuttonbn_pre_enable_plugin_actions tests.
 674       *
 675       * @return array
 676       */
 677      public function bigbluebuttonbn_pre_enable_plugin_actions_provider(): array {
 678          return [
 679              'Initially unset' => [
 680                  null,
 681                  false,
 682                  1,
 683              ],
 684              'Set to false' => [
 685                  false,
 686                  false,
 687                  1,
 688              ],
 689              'Initially set' => [
 690                  true,
 691                  true,
 692                  0,
 693              ],
 694          ];
 695      }
 696  }