Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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/>./*** Tests for the Big Blue Button Instance.** @package mod_bigbluebuttonbn* @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace mod_bigbluebuttonbn;use advanced_testcase;use moodle_exception;/*** Tests for the Big Blue Button Instance.** @package mod_bigbluebuttonbn* @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later* @coversDefaultClass \mod_bigbluebuttonbn\instance*/class instance_test extends advanced_testcase {/*** Test get from** @param string $function* @param string $field* @dataProvider get_from_location_provider* @covers ::get_from_instanceid* @covers ::get_from_cmid*/public function test_get_from(string $function, string $field): void {$this->resetAfterTest();['record' => $record,] = $this->get_test_instance();$instance = call_user_func("mod_bigbluebuttonbn\instance::{$function}", $record->{$field});$this->assertInstanceOf(instance::class, $instance);$this->assertEquals($record->id, $instance->get_instance_id());$this->assertEquals($record->cmid, $instance->get_cm_id());$this->assertEquals($record->cmid, $instance->get_cm()->id);}/*** Get from location provider** @return string[][]*/public function get_from_location_provider(): array {return [['get_from_instanceid', 'id'],['get_from_cmid', 'cmid'],];}/*** Get an instance from a cmid.* @covers ::get_from_cmid*/public function test_get_from_cmid(): void {$this->resetAfterTest();['record' => $record,'cm' => $cm,] = $this->get_test_instance();$instance = instance::get_from_cmid($cm->id);$this->assertInstanceOf(instance::class, $instance);$this->assertEquals($record->id, $instance->get_instance_id());$this->assertEquals($cm->id, $instance->get_cm()->id);}/*** If the instance was not found, and exception should be thrown.* @covers ::get_from_cmid*/public function test_get_from_cmid_not_found(): void {$this->assertNull(instance::get_from_cmid(100));}/*** If the instance was not found, and exception should be thrown.* @covers ::get_from_instanceid*/public function test_get_from_instance_not_found(): void {$this->assertNull(instance::get_from_instanceid(100));}/*** Get from meeting id** @covers ::get_from_meetingid*/public function test_get_from_meetingid(): void {$this->resetAfterTest();['record' => $record,] = $this->get_test_instance();// The meetingid is confusingly made up of a meetingid field, courseid, instanceid, and groupid.$instance = instance::get_from_meetingid(sprintf("%s-%s-%s",$record->meetingid,$record->course,$record->id));$this->assertInstanceOf(instance::class, $instance);$this->assertEquals($record->id, $instance->get_instance_id());$this->assertEquals($record->cmid, $instance->get_cm_id());$this->assertEquals($record->cmid, $instance->get_cm()->id);}/*** Get the get_from_meetingid() function where the meetingid includes a groupid.** @covers ::get_from_meetingid*/public function test_get_from_meetingid_group(): void {$this->resetAfterTest();['record' => $record,'course' => $course,'cm' => $cm,] = $this->get_test_instance();$group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);$instance = instance::get_from_meetingid(sprintf("%s-%s-%s[0]", $record->meetingid, $record->course, $record->id));$this->assertEquals($cm->instance, $instance->get_instance_id());$this->assertEquals($cm->id, $instance->get_cm_id());}/*** Test getting Meeting ID from log as Log field (meetingid) is the full meeting id (with courseid, and bigbluebuttonid).** @covers ::get_from_meetingid*/public function test_get_from_meetingid_from_log(): void {global $DB;$this->resetAfterTest();['record' => $record,'course' => $course,'cm' => $cm,] = $this->get_test_instance();$instance = instance::get_from_cmid($cm->id);$instance->set_group_id(1);logger::log_meeting_joined_event($instance, 1);// Get the meeting ID from the logged "join" event.$meetingid = $DB->get_field('bigbluebuttonbn_logs', 'meetingid', ['courseid' => $course->id,'bigbluebuttonbnid' => $instance->get_instance_id(),'log' => 'Join',], MUST_EXIST);$retrievedinstance = instance::get_from_meetingid($meetingid);$this->assertEquals($cm->instance, $retrievedinstance->get_instance_id());$this->assertEquals($cm->id, $retrievedinstance->get_cm_id());}/*** Ensure that invalid meetingids throw an appropriate exception.** @dataProvider invalid_meetingid_provider* @param string $meetingid* @covers ::get_from_meetingid*/public function test_get_from_meetingid_invalid(string $meetingid): void {$this->expectException(moodle_exception::class);instance::get_from_meetingid($meetingid);}/*** Provide invalid meeting examples** @return \string[][]*/public function invalid_meetingid_provider(): array {// Meeting IDs are in the formats:// - <meetingid[string]>-<courseid[number]>-<instanceid[number]>// - <meetingid[string]>-<courseid[number]>-<instanceid[number]>[<groupid[number]>]// Note: deducing the group from meeting id will soon be deprecated.return ['Non-numeric instanceid' => ['aaa-123-aaa'],];}/*** Test the get_all_instances_in_course function.** @covers ::get_all_instances_in_course*/public function test_get_all_instances_in_course(): void {$this->resetAfterTest();$course = $this->getDataGenerator()->create_course();$records = [];for ($i = 0; $i < 5; $i++) {$this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course->id,]);}$instances = instance::get_all_instances_in_course($course->id);$this->assertCount(5, $instances);foreach ($instances as $instance) {$this->assertInstanceOf(instance::class, $instance);}}/*** Get test instance from data** @param array $data* @return array*/protected function get_test_instance(array $data = []): array {$course = $this->getDataGenerator()->create_course();$record = $this->getDataGenerator()->create_module('bigbluebuttonbn', array_merge(['course' => $course->id,], $data));$cm = get_fast_modinfo($course)->instances['bigbluebuttonbn'][$record->id];return ['course' => $course,'record' => $record,'cm' => $cm,];}/*** Test the get_meeting_id function for a meeting configured for a group.** @covers ::get_meeting_id*/public function test_get_meeting_id_with_groups(): void {$this->resetAfterTest();['record' => $record,'course' => $course,] = $this->get_test_instance();$group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);$instance = instance::get_from_instanceid($record->id);// No group.$this->assertEquals(sprintf("%s-%s-%s[0]", $record->meetingid, $record->course, $record->id),$instance->get_meeting_id(0));// Specified group.$this->assertEquals(sprintf("%s-%s-%s[%d]", $record->meetingid, $record->course, $record->id, $group->id),$instance->get_meeting_id($group->id));}/*** Test the get_meeting_id function for a meeting configured for a group.** @covers ::get_meeting_id*/public function test_get_meeting_id_without_groups(): void {$this->resetAfterTest();['record' => $record,'course' => $course,] = $this->get_test_instance();$instance = instance::get_from_instanceid($record->id);// No group.$this->assertEquals(sprintf("%s-%s-%s[0]", $record->meetingid, $record->course, $record->id),$instance->get_meeting_id(null));}/*** Data provider to check the various room_available scenarios'** @return array*/public function is_currently_open_provider(): array {return ['No opening or closing time set: Is open' => [null, null, true],'Opening time set in the past, no closing: Is open' => [-DAYSECS, null, true],'Opening time set in the future, no closing: Is closed' => [+DAYSECS, null, false],'Closing time set in the past, no opening: Is closed' => [null, -DAYSECS, false],'Closing time set in the future, no opening: Is open' => [null, +DAYSECS, true],'Opening and closing in the past: Is closed' => [-WEEKSECS, -DAYSECS, false],'Opening and closing in the future: Is closed' => [+DAYSECS, +WEEKSECS, false],'Opening in the past, Closing in the future: Is open' => [-DAYSECS, +DAYSECS, true],];}/*** Check instance currently open** @dataProvider is_currently_open_provider* @param null|int $openingtime* @param null|int $closingtime* @param bool $expected* @covers ::is_currently_open*/public function test_is_currently_open(?int $openingtime, ?int $closingtime, bool $expected): void {$stub = $this->getMockBuilder(instance::class)->onlyMethods(['get_instance_var'])->disableOriginalConstructor()->getMock();if ($openingtime) {$openingtime = $openingtime + time();}if ($closingtime) {$closingtime = $closingtime + time();}$stub->method('get_instance_var')->willReturnCallback(function($var) use ($openingtime, $closingtime) {if ($var === 'openingtime') {return $openingtime;}return $closingtime;});$this->assertEquals($expected, $stub->is_currently_open());}/*** Ensure that the user_must_wait_to_join function works as expectd.** @dataProvider user_must_wait_to_join_provider* @param bool $isadmin* @param bool $ismoderator* @param bool $haswaitingroom* @param bool $expected* @covers ::user_must_wait_to_join*/public function test_user_must_wait_to_join(bool $isadmin, bool $ismoderator, bool $haswaitingroom, bool $expected): void {$stub = $this->getMockBuilder(instance::class)->setMethods(['get_instance_var','is_admin','is_moderator',])->disableOriginalConstructor()->getMock();$stub->method('is_admin')->willReturn($isadmin);$stub->method('is_moderator')->willReturn($ismoderator);$stub->method('get_instance_var')->willReturn($haswaitingroom);$this->assertEquals($expected, $stub->user_must_wait_to_join());}/*** Data provider for the user_must_wait_to_join function.** @return array*/public function user_must_wait_to_join_provider(): array {return ['Admins must never wait to join (waiting disabled)' => [true, false, false, false],'Admins must never wait to join (waiting enabled)' => [true, false, true, false],'Moderators must never wait to join (waiting disabled)' => [false, true, false, false],'Moderators must never wait to join (waiting enabled)' => [false, true, true, false],'Other users must wait to join if waiting enabled' => [false, false, true, true],'Other users cannot wait to join if waiting disabled' => [false, false, false, false],];}/*** Ensure that the does_current_user_count_towards_user_limit function works as expectd.** @dataProvider does_current_user_count_towards_user_limit_provider* @param bool $isadmin* @param bool $ismoderator* @param bool $expected* @covers ::does_current_user_count_towards_user_limit*/public function test_does_current_user_count_towards_user_limit(bool $isadmin,bool $ismoderator,bool $expected): void {$stub = $this->getMockBuilder(instance::class)->setMethods(['is_admin','is_moderator',])->disableOriginalConstructor()->getMock();$stub->method('is_admin')->willReturn($isadmin);$stub->method('is_moderator')->willReturn($ismoderator);$this->assertEquals($expected, $stub->does_current_user_count_towards_user_limit());}/*** Data provider for the does_current_user_count_towards_user_limit function.** @return array*/public function does_current_user_count_towards_user_limit_provider(): array {return ['Admin does not count' => [true, false, false],'Moderator does not count' => [false, true, false],'Other users do count' => [false, false, true],];}/*** Ensure that the does_current_user_count_towards_user_limit function works as expectd.** @dataProvider get_current_user_password_provider* @param bool $isadmin* @param bool $ismoderator* @param bool $expectedmodpassword* @covers ::get_current_user_password*/public function test_get_current_user_password(bool $isadmin, bool $ismoderator, bool $expectedmodpassword): void {$stub = $this->getMockBuilder(instance::class)->setMethods(['is_admin','is_moderator','get_moderator_password','get_viewer_password',])->disableOriginalConstructor()->getMock();$stub->method('is_admin')->willReturn($isadmin);$stub->method('is_moderator')->willReturn($ismoderator);$stub->method('get_moderator_password')->willReturn('Moderator Password');$stub->method('get_viewer_password')->willReturn('Viewer Password');if ($expectedmodpassword) {$this->assertEquals('Moderator Password', $stub->get_current_user_password());} else {$this->assertEquals('Viewer Password', $stub->get_current_user_password());}}/*** Data provider for the get_current_user_password function.** @return array*/public function get_current_user_password_provider(): array {return ['Admin is a moderator' => [true, false, true],'Moderator is a moderator' => [false, true, true],'Others are a viewer' => [false, false, false],];}/*** Ensure that the get_current_user_role function works as expected.** @dataProvider get_current_user_role_provider* @param bool $isadmin* @param bool $ismoderator* @param bool $expectedmodrole* @covers ::get_current_user_role*/public function test_get_current_user_role(bool $isadmin, bool $ismoderator, bool $expectedmodrole): void {$stub = $this->getMockBuilder(instance::class)->setMethods(['is_admin','is_moderator',])->disableOriginalConstructor()->getMock();$stub->method('is_admin')->willReturn($isadmin);$stub->method('is_moderator')->willReturn($ismoderator);if ($expectedmodrole) {$this->assertEquals('MODERATOR', $stub->get_current_user_role());} else {$this->assertEquals('VIEWER', $stub->get_current_user_role());}}/*** Data provider for the get_current_user_role function.** @return array*/public function get_current_user_role_provider(): array {return ['Admin is a moderator' => [true, false, true],'Moderator is a moderator' => [false, true, true],'Others are a viewer' => [false, false, false],];}/*** Tests for the allow_recording_start_stop function.** @dataProvider allow_recording_start_stop_provider* @param bool $isrecorded* @param bool $showbuttons* @param bool $expected* @covers ::allow_recording_start_stop*/public function test_allow_recording_start_stop(bool $isrecorded,bool $showbuttons,bool $expected): void {$stub = $this->getMockBuilder(instance::class)->setMethods(['is_recorded','should_show_recording_button',])->disableOriginalConstructor()->getMock();$stub->method('is_recorded')->willReturn($isrecorded);$stub->method('should_show_recording_button')->willReturn($showbuttons);$this->assertEquals($expected, $stub->allow_recording_start_stop());}/*** Data provider for the allow_recording_start_stop function.** @return array*/public function allow_recording_start_stop_provider(): array {return ['Meeting is not recorded: No start/stop' => [false, false, false],'Meeting recorded, Buttons shown: Allow' => [true, true, true],'Meeting recorded, Buttons not shown: Deny' => [true, false, false],];}/*** Test get user id (guest or current user)* @covers \mod_bigbluebuttonbn\instance::get_user_id*/public function test_get_user_id(): void {$this->resetAfterTest();$this->setUser(null);['record' => $record ] = $this->get_test_instance();$instance = instance::get_from_instanceid($record->id);$this->assertEquals(0, $instance->get_user_id());$user = $this->getDataGenerator()->create_user();$this->setUser($user);$this->assertEquals($user->id, $instance->get_user_id());}/*** Test guest access URL** @covers ::get_guest_access_url*/public function test_get_guest_access_url(): void {global $CFG;$this->resetAfterTest();['record' => $record ] = $this->get_test_instance(['guestallowed' => true]);$CFG->bigbluebuttonbn['guestaccess_enabled'] = 1;$instance = instance::get_from_instanceid($record->id);$this->assertNotEmpty($instance->get_guest_access_url());}/*** Test guest allowed flag** @covers ::is_guest_allowed*/public function test_is_guest_allowed(): void {global $CFG;$this->resetAfterTest();['record' => $record ] = $this->get_test_instance(['guestallowed' => true]);$CFG->bigbluebuttonbn['guestaccess_enabled'] = 1;$instance = instance::get_from_instanceid($record->id);$this->assertTrue($instance->is_guest_allowed());$CFG->bigbluebuttonbn['guestaccess_enabled'] = 0;$this->assertFalse($instance->is_guest_allowed());}/*** Test private method get_instance_info_retriever** @covers ::get_instance_info_retriever*/public function test_get_instance_info_retriever(): void {$this->resetAfterTest();['record' => $record,'cm' => $cm,] = $this->get_test_instance();$instance = instance::get_from_instanceid($record->id);$instancereflection = new \ReflectionClass($instance);$getinstanceinforetriever = $instancereflection->getMethod('get_instance_info_retriever');$this->assertInstanceOf('\mod_bigbluebuttonbn\instance',$getinstanceinforetriever->invoke($instance, $record->id, instance::IDTYPE_INSTANCEID));$this->assertEquals($cm->id, $instance->get_cm_id());}/*** Test guest access password** @covers ::get_guest_access_password*/public function get_guest_access_password() {global $CFG;$this->resetAfterTest();['record' => $record ] = $this->get_test_instance(['guestallowed' => true]);$CFG->bigbluebuttonbn['guestaccess_enabled'] = 1;$instance = instance::get_from_instanceid($record->id);$this->assertNotEmpty($instance->get_guest_access_password());}}