Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 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 * Behat custom steps and configuration for mod_bigbluebuttonbn. 19 * 20 * @package mod_bigbluebuttonbn 21 * @category test 22 * @copyright 2021 Andrew Lyons <andrew@nicols.co.uk> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 require_once (__DIR__ . '/../../../../lib/behat/behat_base.php'); 27 28 use Behat\Behat\Hook\Scope\BeforeScenarioScope; 29 use Behat\Gherkin\Node\TableNode; 30 use mod_bigbluebuttonbn\instance; 31 use mod_bigbluebuttonbn\test\subplugins_test_helper_trait; 32 use Moodle\BehatExtension\Exception\SkippedException; 33 require_once(__DIR__ . '../../../classes/test/subplugins_test_helper_trait.php'); 34 /** 35 * Behat custom steps and configuration for mod_bigbluebuttonbn. 36 * 37 * @package mod_bigbluebuttonbn 38 * @copyright 2021 Andrew Lyons <andrew@nicols.co.uk> 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class behat_mod_bigbluebuttonbn extends behat_base { 42 use subplugins_test_helper_trait; 43 44 /** 45 * @var array List of installed subplugins. 46 */ 47 protected $installedsubplugins = []; 48 49 /** 50 * BeforeScenario hook to reset the remote testpoint. 51 * 52 * @BeforeScenario @mod_bigbluebuttonbn 53 * 54 * @param BeforeScenarioScope $scope 55 */ 56 public function before_scenario(BeforeScenarioScope $scope) { 57 if (defined('TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER')) { 58 $this->send_mock_request('backoffice/reset'); 59 } 60 } 61 62 /** 63 * Accept dpa and enable bigbluebuttonbn plugin. 64 * 65 * @When /^I accept dpa and enable bigbluebuttonbn plugin$/ 66 */ 67 public function i_accept_dpa_and_enable_bigbluebuttonbn_plugin(): void { 68 set_config('bigbluebuttonbn_default_dpa_accepted', true); 69 $this->execute('behat_general::i_enable_plugin', ['bigbluebuttonbn', 'mod']); 70 } 71 72 /** 73 * Check that the TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER is defined, so we can connect to the mock server. 74 * 75 * @Given /^a BigBlueButton mock server is configured$/ 76 */ 77 public function mock_is_configured(): void { 78 if (!defined('TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER')) { 79 throw new SkippedException( 80 'The TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER constant must be defined to run mod_bigbluebuttonbn tests' 81 ); 82 } 83 84 set_config('bigbluebuttonbn_server_url', TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER); 85 } 86 87 /** 88 * Return the list of exact named selectors. 89 * 90 * @return array 91 */ 92 public static function get_exact_named_selectors(): array { 93 return [ 94 new behat_component_named_selector('Meeting field', [ 95 <<<XPATH 96 .//*[@data-identifier=%locator%] 97 XPATH 98 ], false), 99 ]; 100 } 101 102 /** 103 * Retrieve the mock server URL from the TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER definition 104 * 105 * @param string $endpoint 106 * @param array $params 107 * @return moodle_url 108 */ 109 public static function get_mocked_server_url(string $endpoint = '', array $params = []): moodle_url { 110 return new moodle_url(TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER . '/' . $endpoint, $params); 111 } 112 113 /** 114 * Send a query to the mock server 115 * 116 * @param string $endpoint 117 * @param array $params 118 */ 119 protected function send_mock_request(string $endpoint, array $params = []): void { 120 $url = $this->get_mocked_server_url($endpoint, $params); 121 122 $curl = new \curl(); 123 $curl->get($url->out_omit_querystring(), $url->params()); 124 } 125 126 /** 127 * Convert page names to URLs for steps like 'When I am on the "[page name]" page'. 128 * 129 * Recognised page names are: 130 * | None so far! | | 131 * 132 * @param string $page name of the page, with the component name removed e.g. 'Admin notification'. 133 * @return moodle_url the corresponding URL. 134 * @throws Exception with a meaningful error message if the specified page cannot be found. 135 */ 136 protected function resolve_page_url(string $page): moodle_url { 137 throw new Exception("Unrecognised page type '{$page}'."); 138 } 139 140 /** 141 * Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'. 142 * 143 * Recognised page names are: 144 * | pagetype | name meaning | description | 145 * | Index | BBB Course Index | The bbb index page (index.php) | 146 * 147 * @param string $type identifies which type of page this is, e.g. 'Indez'. 148 * @param string $identifier identifies the particular page, e.g. 'Mathematics 101'. 149 * @return moodle_url the corresponding URL. 150 * @throws Exception with a meaningful error message if the specified page cannot be found. 151 */ 152 protected function resolve_page_instance_url(string $type, string $identifier): moodle_url { 153 switch ($type) { 154 case 'Index': 155 $this->get_course_id($identifier); 156 return new moodle_url('/mod/bigbluebuttonbn/index.php', [ 157 'id' => $this->get_course_id($identifier), 158 ]); 159 case 'BigblueButtonBN Guest': 160 $cm = $this->get_cm_by_activity_name('bigbluebuttonbn', $identifier); 161 $instance = instance::get_from_cmid($cm->id); 162 $url = $instance->get_guest_access_url(); 163 // We have to make sure we set the password. It makes it then easy to submit the form with the right password. 164 $url->param('password', $instance->get_guest_access_password()); 165 return $url; 166 default: 167 throw new Exception("Unrecognised page type '{$type}'."); 168 } 169 } 170 171 /** 172 * Get course id from its identifier (shortname or fullname or idnumber) 173 * 174 * @param string $identifier 175 * @return int 176 */ 177 protected function get_course_id(string $identifier): int { 178 global $DB; 179 180 return $DB->get_field_select( 181 'course', 182 'id', 183 "shortname = :shortname OR fullname = :fullname OR idnumber = :idnumber", 184 [ 185 'shortname' => $identifier, 186 'fullname' => $identifier, 187 'idnumber' => $identifier, 188 ], 189 MUST_EXIST 190 ); 191 } 192 193 /** 194 * Trigger a recording ready notification on BBB side 195 * 196 * @Given the BigBlueButtonBN server has sent recording ready notifications 197 */ 198 public function trigger_recording_ready_notification(): void { 199 $this->send_mock_request('backoffice/sendRecordingReadyNotifications', [ 200 'secret' => \mod_bigbluebuttonbn\local\config::DEFAULT_SHARED_SECRET, 201 ] 202 ); 203 } 204 205 /** 206 * Trigger a meeting event on BBB side 207 * 208 * @Given /^the BigBlueButtonBN server has received the following events from user "(?P<element_string>(?:[^"]|\\")*)":$/ 209 * @param string $username 210 * @param TableNode $data 211 */ 212 public function trigger_meeting_event(string $username, TableNode $data): void { 213 global $DB; 214 $user = core_user::get_user_by_username($username); 215 $rows = $data->getHash(); 216 foreach ($rows as $elementdata) { 217 $instanceid = $DB->get_field('bigbluebuttonbn', 'id', [ 218 'name' => $elementdata['instancename'], 219 ]); 220 $instance = \mod_bigbluebuttonbn\instance::get_from_instanceid($instanceid); 221 $this->send_mock_request('backoffice/addMeetingEvent', [ 222 'secret' => \mod_bigbluebuttonbn\local\config::DEFAULT_SHARED_SECRET, 223 'meetingID' => $instance->get_meeting_id(), 224 'attendeeID' => $user->id, 225 'attendeeName' => fullname($user), 226 'eventType' => $elementdata['eventtype'], 227 'eventData' => $elementdata['eventdata'] ?? '', 228 ] 229 ); 230 } 231 } 232 /** 233 * Send all events received for this meeting back to moodle 234 * 235 * @Given /^the BigBlueButtonBN activity "(?P<element_string>(?:[^"]|\\")*)" has sent recording all its events$/ 236 * @param string $instancename 237 */ 238 public function trigger_all_events(string $instancename): void { 239 global $DB; 240 241 $instanceid = $DB->get_field('bigbluebuttonbn', 'id', [ 242 'name' => $instancename, 243 ]); 244 $instance = \mod_bigbluebuttonbn\instance::get_from_instanceid($instanceid); 245 $this->send_mock_request('backoffice/sendAllEvents', [ 246 'meetingID' => $instance->get_meeting_id(), 247 'sendQuery' => true 248 ] 249 ); 250 } 251 252 /** 253 * Install the simple subplugin 254 * 255 * Important note here. Originally we had a step that was installing the plugin, however 256 * because of race condition (mainly javascript calls), the hack to the core_component was 257 * randomly lost due to the component cache being cleared. So we have to install the plugin before 258 * any interaction with the site. 259 * @BeforeScenario @with_bbbext_simple 260 */ 261 public function install_simple_subplugin() { 262 $this->setup_fake_plugin("simple"); 263 $mockedcomponent = new ReflectionClass(core_component::class); 264 $mockedplugintypes = $mockedcomponent->getProperty('plugintypes'); 265 $mockedplugintypes->setAccessible(true); 266 $mockedplugintypes->setValue(null, null); 267 $init = $mockedcomponent->getMethod('init'); 268 $init->setAccessible(true); 269 $init->invoke(null); 270 // I enable the plugin. 271 $manager = core_plugin_manager::resolve_plugininfo_class(\mod_bigbluebuttonbn\extension::BBB_EXTENSION_PLUGIN_NAME); 272 $manager::enable_plugin("simple", true); 273 } 274 275 /** 276 * Uninstall the simple subplugin 277 * 278 * @AfterScenario @with_bbbext_simple 279 */ 280 public function uninstall_simple_subplugin() { 281 $this->uninstall_fake_plugin("simple"); 282 } 283 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body