343 lines
13 KiB
PHP
343 lines
13 KiB
PHP
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* BBB Library tests class trait.
|
|
*
|
|
* @package mod_bigbluebuttonbn
|
|
* @copyright 2018 - present, Blindside Networks Inc
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
* @author Laurent David (laurent@call-learning.fr)
|
|
*/
|
|
namespace mod_bigbluebuttonbn\test;
|
|
|
|
use context_module;
|
|
use mod_bigbluebuttonbn\instance;
|
|
use mod_bigbluebuttonbn\local\proxy\recording_proxy;
|
|
use mod_bigbluebuttonbn\meeting;
|
|
use stdClass;
|
|
use testing_data_generator;
|
|
use core\plugininfo\mod;
|
|
|
|
trait testcase_helper_trait {
|
|
/** @var testing_data_generator|null */
|
|
protected $generator = null;
|
|
|
|
/** @var object|null */
|
|
protected $course = null;
|
|
|
|
/**
|
|
* Convenience function to create an instance of a bigbluebuttonactivty.
|
|
*
|
|
* @param stdClass|null $course course to add the module to
|
|
* @param array $params Array of parameters to pass to the generator
|
|
* @param array $options Array of options to pass to the generator
|
|
* @return array($context, $cm, $instance) Testable wrapper around the assign class.
|
|
*/
|
|
protected function create_instance(?stdClass $course = null, array $params = [], array $options = []): array {
|
|
// Prior to creating the instance, make sure that the BigBlueButton module is enabled.
|
|
$modules = \core_plugin_manager::instance()->get_plugins_of_type('mod');
|
|
if (!$modules['bigbluebuttonbn']->is_enabled()) {
|
|
mod::enable_plugin('bigbluebuttonbn', true);
|
|
}
|
|
|
|
if (!$course) {
|
|
$course = $this->get_course();
|
|
}
|
|
$params['course'] = $course->id;
|
|
$options['visible'] = 1;
|
|
$instance = $this->getDataGenerator()->create_module('bigbluebuttonbn', $params, $options);
|
|
list($course, $cm) = get_course_and_cm_from_instance($instance, 'bigbluebuttonbn');
|
|
$context = context_module::instance($cm->id);
|
|
|
|
return [$context, $cm, $instance];
|
|
}
|
|
|
|
/**
|
|
* Get the matching form data
|
|
*
|
|
* @param stdClass $bbactivity the current bigbluebutton activity
|
|
* @param stdClass|null $course the course or null (taken from $this->get_course() if null)
|
|
* @return mixed
|
|
*/
|
|
protected function get_form_data_from_instance(stdClass $bbactivity, ?stdClass $course = null): object {
|
|
global $USER;
|
|
|
|
if (!$course) {
|
|
$course = $this->get_course();
|
|
}
|
|
$this->setAdminUser();
|
|
$bbactivitycm = get_coursemodule_from_instance('bigbluebuttonbn', $bbactivity->id);
|
|
list($cm, $context, $module, $data, $cw) = get_moduleinfo_data($bbactivitycm, $course);
|
|
$this->setUser($USER);
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Get or create course if it does not exist
|
|
*
|
|
* @return stdClass|null
|
|
*/
|
|
protected function get_course(): stdClass {
|
|
if (!$this->course) {
|
|
$this->course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]);
|
|
}
|
|
return $this->course;
|
|
}
|
|
|
|
/**
|
|
* Generate a course, several students and several groups
|
|
*
|
|
* @param stdClass $courserecord
|
|
* @param int $numstudents
|
|
* @param int $numteachers
|
|
* @param int $groupsnum
|
|
* @return array
|
|
*/
|
|
protected function setup_course_students_teachers(stdClass $courserecord, int $numstudents, int $numteachers,
|
|
int $groupsnum): array {
|
|
global $DB;
|
|
$generator = $this->getDataGenerator();
|
|
$course = $generator->create_course($courserecord);
|
|
$groups = [];
|
|
for ($i = 0; $i < $groupsnum; $i++) {
|
|
$groups[] = $generator->create_group(['courseid' => $course->id]);
|
|
}
|
|
$generator->create_group(['courseid' => $course->id]);
|
|
$generator->create_group(['courseid' => $course->id]);
|
|
|
|
$roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
|
|
|
|
$students = [];
|
|
for ($i = 0; $i < $numstudents; $i++) {
|
|
$student = $generator->create_user();
|
|
$generator->enrol_user($student->id, $course->id, $roleids['student']);
|
|
$groupid = $groups[$i % $groupsnum]->id;
|
|
groups_add_member($groupid, $student->id);
|
|
$students[] = $student;
|
|
}
|
|
|
|
$teachers = [];
|
|
for ($i = 0; $i < $numteachers; $i++) {
|
|
$teacher = $generator->create_user();
|
|
$generator->enrol_user($teacher->id, $course->id, $roleids['teacher']);
|
|
$groupid = $groups[$i % $groupsnum]->id;
|
|
groups_add_member($groupid, $teacher->id);
|
|
$teachers[] = $teacher;
|
|
}
|
|
$bbactivity = $generator->create_module(
|
|
'bigbluebuttonbn',
|
|
['course' => $course->id],
|
|
['visible' => true]);
|
|
|
|
get_fast_modinfo(0, 0, true);
|
|
return [$course, $groups, $students, $teachers, $bbactivity, $roleids];
|
|
}
|
|
|
|
/**
|
|
* This test requires mock server to be present.
|
|
*/
|
|
protected function initialise_mock_server(): void {
|
|
if (!defined('TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER')) {
|
|
$this->markTestSkipped(
|
|
'The TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER constant must be defined to run mod_bigbluebuttonbn tests'
|
|
);
|
|
}
|
|
try {
|
|
$this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn')->reset_mock();
|
|
} catch (\moodle_exception $e) {
|
|
$this->markTestSkipped(
|
|
'Cannot connect to the mock server for this test. Make sure that TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER points
|
|
to an active Mock server'
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an return an array of recordings
|
|
*
|
|
* @param instance $instance
|
|
* @param array $recordingdata array of recording information
|
|
* @param array $additionalmeetingdata
|
|
* @return array
|
|
*/
|
|
protected function create_recordings_for_instance(instance $instance, array $recordingdata = [],
|
|
$additionalmeetingdata = []): array {
|
|
$recordings = [];
|
|
$bbbgenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
|
|
// Create the meetings on the mock server, so like this we can find the recordings.
|
|
$meeting = new meeting($instance);
|
|
$meeting->update_cache(); // The meeting has just been created but we need to force fetch info from the server.
|
|
if (!$meeting->is_running()) {
|
|
$additionalmeetingdata = array_merge([
|
|
'instanceid' => $instance->get_instance_id(),
|
|
'groupid' => $instance->get_group_id()
|
|
], $additionalmeetingdata);
|
|
$bbbgenerator->create_meeting($additionalmeetingdata);
|
|
}
|
|
foreach ($recordingdata as $rindex => $data) {
|
|
$recordings[] = $bbbgenerator->create_recording(
|
|
array_merge([
|
|
'bigbluebuttonbnid' => $instance->get_instance_id(),
|
|
'groupid' => $instance->get_group_id()
|
|
], $data)
|
|
);
|
|
}
|
|
return $recordings;
|
|
}
|
|
|
|
/**
|
|
* Create an activity which includes a set of recordings.
|
|
*
|
|
* @param stdClass $course
|
|
* @param int $type
|
|
* @param array $recordingdata array of recording information
|
|
* @param int $groupid
|
|
* @return array
|
|
*/
|
|
protected function create_activity_with_recordings(stdClass $course, int $type, array $recordingdata, int $groupid = 0): array {
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
|
|
|
|
$activity = $generator->create_instance([
|
|
'course' => $course->id,
|
|
'type' => $type
|
|
]);
|
|
|
|
$instance = instance::get_from_instanceid($activity->id);
|
|
$instance->set_group_id($groupid);
|
|
$recordings = $this->create_recordings_for_instance($instance, $recordingdata);
|
|
return [
|
|
'course' => $course,
|
|
'activity' => $activity,
|
|
'recordings' => $recordings,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Create a course, users and recording from dataset given in an array form
|
|
*
|
|
* @param array $dataset
|
|
* @return mixed
|
|
*/
|
|
protected function create_from_dataset(array $dataset) {
|
|
list('type' => $type, 'recordingsdata' => $recordingsdata, 'groups' => $groups,
|
|
'users' => $users) = $dataset;
|
|
$plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
|
|
|
|
$coursedata = empty($groups) ? [] : ['groupmodeforce' => true, 'groupmode' => $dataset['coursemode'] ?? VISIBLEGROUPS];
|
|
$this->course = $this->getDataGenerator()->create_course($coursedata);
|
|
|
|
foreach ($users as $userdata) {
|
|
$this->getDataGenerator()->create_and_enrol($this->course, $userdata['role'], ['username' => $userdata['username']]);
|
|
}
|
|
|
|
if ($groups) {
|
|
foreach ($groups as $groupname => $students) {
|
|
$group = $this->getDataGenerator()->create_group(['name' => $groupname, 'courseid' => $this->course->id]);
|
|
foreach ($students as $username) {
|
|
$user = \core_user::get_user_by_username($username);
|
|
$this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);
|
|
}
|
|
}
|
|
}
|
|
$instancesettings = [
|
|
'course' => $this->course->id,
|
|
'type' => $type,
|
|
'name' => 'Example',
|
|
];
|
|
if (!empty($dataset['additionalsettings'])) {
|
|
$instancesettings = array_merge($instancesettings, $dataset['additionalsettings']);
|
|
}
|
|
$activity = $plugingenerator->create_instance($instancesettings);
|
|
$instance = instance::get_from_instanceid($activity->id);
|
|
foreach ($recordingsdata as $groupname => $recordings) {
|
|
if ($groups) {
|
|
$groupid = groups_get_group_by_name($this->course->id, $groupname);
|
|
$instance->set_group_id($groupid);
|
|
}
|
|
$this->create_recordings_for_instance($instance, $recordings);
|
|
}
|
|
return $activity->id;
|
|
}
|
|
|
|
/**
|
|
* Create the legacy log entries for this task.
|
|
*
|
|
* @param instance $instance
|
|
* @param int $userid
|
|
* @param int $count
|
|
* @param bool $importedrecordings
|
|
* @param bool $withremoterecordings create recording on the mock server ?
|
|
* @return array
|
|
*/
|
|
protected function create_log_entries(
|
|
instance $instance,
|
|
int $userid,
|
|
int $count = 30,
|
|
bool $importedrecordings = false,
|
|
bool $withremoterecordings = true
|
|
): array {
|
|
// Create log entries for each (30 for the ungrouped, 30 for the grouped).
|
|
$baselogdata = [
|
|
'courseid' => $instance->get_course_id(),
|
|
'userid' => $userid,
|
|
'log' => $importedrecordings ? 'Import' : 'Create',
|
|
'meta' => json_encode(['record' => true]),
|
|
'imported' => $importedrecordings,
|
|
];
|
|
$plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if ($withremoterecordings) {
|
|
// Create a recording.
|
|
$starttime = time() - random_int(HOURSECS, WEEKSECS);
|
|
$recording = $plugingenerator->create_recording([
|
|
'bigbluebuttonbnid' => $instance->get_instance_id(),
|
|
'groupid' => $instance->get_group_id(),
|
|
'starttime' => $starttime,
|
|
'endtime' => $starttime + HOURSECS,
|
|
], true); // Create them on the server only.
|
|
|
|
$baselogdata['meetingid'] = $instance->get_meeting_id();
|
|
if ($importedrecordings) {
|
|
// Fetch the data.
|
|
$data = recording_proxy::fetch_recordings([$recording->recordingid]);
|
|
$data = end($data);
|
|
if ($data) {
|
|
$metaonly = array_filter($data, function($key) {
|
|
return strstr($key, 'meta_');
|
|
}, ARRAY_FILTER_USE_KEY);
|
|
} else {
|
|
$data = [];
|
|
}
|
|
$baselogdata['meta'] = json_encode(array_merge([
|
|
'recording' => array_diff_key($data, $metaonly),
|
|
], $metaonly));
|
|
|
|
} else {
|
|
$baselogdata['meta'] = json_encode((object) ['record' => true]);
|
|
}
|
|
}
|
|
// Insert the legacy log entry.
|
|
$logs[] = $plugingenerator->create_log(array_merge($baselogdata, [
|
|
'bigbluebuttonbnid' => $instance->get_instance_id(),
|
|
'timecreated' => time() - random_int(HOURSECS, WEEKSECS) + (HOURSECS * $i),
|
|
]));
|
|
}
|
|
|
|
return $logs;
|
|
}
|
|
}
|