See Release Notes
Long Term Support Release
Differences Between: [Versions 400 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 /** 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 mod_bigbluebuttonbn\test\testcase_helper_trait; 29 use restore_date_testcase; 30 use stdClass; 31 32 defined('MOODLE_INTERNAL') || die(); 33 global $CFG; 34 require_once($CFG->libdir . "/phpunit/classes/restore_date_testcase.php"); 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 \backup_bigbluebuttonbn_activity_task 44 * @covers \restore_bigbluebuttonbn_activity_task 45 */ 46 class backup_restore_test extends restore_date_testcase { 47 use testcase_helper_trait; 48 49 /** 50 * Setup 51 */ 52 public function setUp(): void { 53 parent::setUp(); 54 } 55 56 /** 57 * All instance types 58 */ 59 const ALL_TYPES = [ 60 'Instance Type ALL' => instance::TYPE_ALL, 61 'Instance Type Recording Only' => instance::TYPE_RECORDING_ONLY, 62 'Instance Room Only' => instance::TYPE_ROOM_ONLY 63 ]; 64 65 /** 66 * Test backup restore (basic) 67 */ 68 public function test_backup_restore(): void { 69 global $DB; 70 $this->resetAfterTest(); 71 $bbactivity = []; 72 foreach (self::ALL_TYPES as $key => $type) { 73 list($bbactivitycontext, $bbactivitycm, $bbactivity[$type]) 74 = $this->create_instance($this->get_course(), ['type' => $type]); 75 } 76 77 $newcourseid = $this->backup_and_restore($this->get_course()); 78 79 foreach (self::ALL_TYPES as $key => $type) { 80 $newbbb = 81 $DB->get_record('bigbluebuttonbn', ['course' => $newcourseid, 'type' => $type], '*', MUST_EXIST); 82 // One record. 83 $this->assert_bbb_activities_same($bbactivity[$type], $newbbb); 84 $this->assertEquals($bbactivity[$type]->meetingid, $newbbb->meetingid); 85 } 86 } 87 88 /** 89 * @var $RECORDINGS_DATA array fake recording data. 90 */ 91 const RECORDINGS_DATA = [ 92 ['name' => 'Recording 1'], 93 ['name' => 'Recording 2'], 94 ]; 95 96 /** 97 * Check backup restore with recordings 98 * 99 */ 100 public function test_backup_restore_with_recordings(): void { 101 global $DB; 102 $this->resetAfterTest(); 103 $this->initialise_mock_server(); 104 set_config('bigbluebuttonbn_importrecordings_enabled', 1); 105 // This is for imported recording. 106 $generator = $this->getDataGenerator(); 107 $othercourse = $generator->create_course(); 108 $otherbbbactivities = []; 109 $recordingstoimport = []; 110 111 list('activity' => $otherbbbactivities[], 'recordings' => $recordings) = 112 $this->create_activity_with_recordings($othercourse, 113 instance::TYPE_ALL, self::RECORDINGS_DATA 114 ); 115 $recordingstoimport = array_merge($recordingstoimport, $recordings); 116 list('activity' => $otherbbbactivities[], 'recordings' => $recordings) = 117 $this->create_activity_with_recordings($this->get_course(), 118 instance::TYPE_ALL, self::RECORDINGS_DATA 119 ); 120 $recordingstoimport = array_merge($recordingstoimport, $recordings); 121 // Create a set of recordings and imported recordings. 122 // We have nbrecording per bb activity, except for roomonly recordings which have the imported recordings. 123 $bbactivity = []; 124 foreach (self::ALL_TYPES as $key => $type) { 125 $bbactivity[$type] = $this->getDataGenerator()->create_module( 126 'bigbluebuttonbn', 127 ['course' => $this->get_course()->id, 'type' => $type, 'name' => 'BBB Activity:' . $key], 128 ['visible' => true] 129 ); 130 $instance = instance::get_from_instanceid($bbactivity[$type]->id); 131 // Create recording except for TYPE_RECORDING_ONLY Only. 132 if ($instance->is_feature_enabled('showroom')) { 133 $this->create_recordings_for_instance(instance::get_from_instanceid($bbactivity[$type]->id), 134 self::RECORDINGS_DATA); 135 } 136 // Then import the recordings into the instance. 137 if ($instance->is_feature_enabled('importrecordings')) { 138 foreach ($recordingstoimport as $rec) { 139 $rentity = recording::get_record(['id' => $rec->id]); 140 if ($rentity->get('bigbluebuttonbnid') != $instance->get_instance_id()) { 141 $rentity->create_imported_recording($instance); 142 } 143 } 144 } 145 } 146 147 // Backup and restore steps. 148 $nbrecordings = count(self::RECORDINGS_DATA); 149 $newcourseid = $this->backup_and_restore($this->get_course()); 150 151 // Now checks. 152 foreach (self::ALL_TYPES as $key => $type) { 153 $newbbb = 154 $DB->get_record('bigbluebuttonbn', 155 ['course' => $newcourseid, 'type' => $type, 'name' => 'BBB Activity:' . $key], 156 '*', 157 MUST_EXIST); // One record. 158 $this->assert_bbb_activities_same($bbactivity[$type], $newbbb); 159 $newinstance = instance::get_from_instanceid($newbbb->id); 160 161 $instancerecordings = $newinstance->get_recordings(); 162 // Type ROOM_ONLY & TYPE_ALL : all assigned recordings (NB_RECORDINGS). 163 // Type TYPE_RECORDING_ONLY: all recordings from this course (i.e. 164 // existing recording (NB_RECORDING) + ROOM_ONLY(NB_RECORDING) + TYPE_ALL (NB_RECORDING)). 165 $expectedcount = $type == instance::TYPE_RECORDING_ONLY ? $nbrecordings * 3 : $nbrecordings; 166 // Type ROOM_ONLY & TYPE_ALL : The imported recording (NB_RECORDING*2 here) 167 // Type TYPE_RECORDING_ONLY: imported recordings we add the imported recording from the other activity (TYPE_ALL). 168 $expectedcount += $type == instance::TYPE_RECORDING_ONLY ? count($recordingstoimport) : 0; 169 // We managed to import recording in this activity, so let's add them. 170 $expectedcount += $newinstance->is_feature_enabled('importrecordings') ? count($recordingstoimport) : 0; 171 $this->assertCount($expectedcount, 172 $instancerecordings, 'Wrong count for instance Type:' . $key); 173 // Then check imported recordings. 174 foreach ($instancerecordings as $rec) { 175 if ($rec->get('imported')) { 176 $importeddata = json_decode($rec->get('importeddata')); 177 $this->assertNotEmpty($importeddata); 178 } 179 } 180 } 181 } 182 183 /** 184 * Check duplicating activity does not duplicate meeting id 185 * 186 * @dataProvider bbb_type_provider 187 */ 188 public function test_duplicate_module_no_meetingid(int $type) { 189 list($bbactivitycontext, $bbactivitycm, $bbactivity) 190 = $this->create_instance($this->get_course(), ['type' => $type]); 191 $newcm = duplicate_module($this->get_course(), $bbactivitycm); 192 $oldinstance = instance::get_from_cmid($bbactivitycm->id); 193 $newinstance = instance::get_from_cmid($newcm->id); 194 195 $this->assertNotEquals($oldinstance->get_instance_var('meetingid'), $newinstance->get_instance_var('meetingid')); 196 } 197 198 /** 199 * Check that using the recycle bin keeps the meeting id 200 * 201 * @dataProvider bbb_type_provider 202 */ 203 public function test_recycle_module_keep_meetingid(int $type) { 204 list($bbactivitycontext, $bbactivitycm, $bbactivity) 205 = $this->create_instance($this->get_course(), ['type' => $type]); 206 // Delete the course module. 207 course_delete_module($bbactivitycm->id); 208 // Now, run the course module deletion adhoc task. 209 \phpunit_util::run_all_adhoc_tasks(); 210 $currentinstances = instance::get_all_instances_in_course($this->course->id); 211 $this->assertEmpty($currentinstances); 212 // Try restoring. 213 $recyclebin = new \tool_recyclebin\course_bin($this->course->id); 214 foreach ($recyclebin->get_items() as $item) { 215 $recyclebin->restore_item($item); 216 } 217 $restoredinstance = instance::get_all_instances_in_course($this->course->id); 218 $restoredinstance = end($restoredinstance); 219 $this->assertEquals($restoredinstance->get_instance_var('meetingid'), $bbactivity->meetingid); 220 } 221 222 /** 223 * Return an array of BigBlueButton types 224 * @return array[] 225 */ 226 public function bbb_type_provider() { 227 return [ 228 'All' => [instance::TYPE_ALL], 229 'Recording Only' => [instance::TYPE_RECORDING_ONLY], 230 'Room Only' => [instance::TYPE_ROOM_ONLY] 231 ]; 232 } 233 234 /** 235 * Check two bbb activities are the same 236 * 237 * @param stdClass $bbboriginal 238 * @param stdClass $bbbdest 239 */ 240 protected function assert_bbb_activities_same(stdClass $bbboriginal, stdClass $bbbdest) { 241 $this->assertNotFalse($bbbdest); 242 $filterfunction = function($key) { 243 return !in_array($key, ['course', 'cmid', 'id', 'guestlinkuid', 'guestpassword']); 244 }; 245 $this->assertEquals( 246 array_filter((array) $bbboriginal, $filterfunction, ARRAY_FILTER_USE_KEY), 247 array_filter((array) $bbbdest, $filterfunction, ARRAY_FILTER_USE_KEY) 248 ); 249 } 250 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body