MDL-76303 mod_bigbluebuttonbn: Fix userlimit

This commit is contained in:
Shamiso.Jaravaza 2023-03-10 11:18:15 -07:00
parent 794f107e88
commit dca1c7994f
4 changed files with 94 additions and 19 deletions

View file

@ -147,12 +147,12 @@ class meeting {
} }
/** /**
* Number of participants * Total number of moderators and viewers.
* *
* @return int * @return int
*/ */
public function get_participant_count() { public function get_participant_count() {
return $this->get_meeting_info()->participantcount; return $this->get_meeting_info()->totalusercount;
} }
/** /**
@ -253,7 +253,7 @@ class meeting {
$activitystatus = bigbluebutton_proxy::view_get_activity_status($instance); $activitystatus = bigbluebutton_proxy::view_get_activity_status($instance);
// This might raise an exception if info cannot be retrieved. // This might raise an exception if info cannot be retrieved.
// But this might be totally fine as the meeting is maybe not yet created on BBB side. // But this might be totally fine as the meeting is maybe not yet created on BBB side.
$participantcount = 0; $totalusercount = 0;
// This is the default value for any meeting that has not been created. // This is the default value for any meeting that has not been created.
$meetinginfo->statusrunning = false; $meetinginfo->statusrunning = false;
$meetinginfo->createtime = null; $meetinginfo->createtime = null;
@ -262,19 +262,16 @@ class meeting {
if (!empty($info)) { if (!empty($info)) {
$meetinginfo->statusrunning = $info['running'] === 'true'; $meetinginfo->statusrunning = $info['running'] === 'true';
$meetinginfo->createtime = $info['createTime'] ?? null; $meetinginfo->createtime = $info['createTime'] ?? null;
$participantcount = isset($info['participantCount']) ? $info['participantCount'] : 0; $totalusercount = isset($info['participantCount']) ? $info['participantCount'] : 0;
} }
$meetinginfo->statusclosed = $activitystatus === 'ended'; $meetinginfo->statusclosed = $activitystatus === 'ended';
$meetinginfo->statusopen = !$meetinginfo->statusrunning && $activitystatus === 'open'; $meetinginfo->statusopen = !$meetinginfo->statusrunning && $activitystatus === 'open';
$meetinginfo->participantcount = $participantcount; $meetinginfo->totalusercount = $totalusercount;
$canjoin = !$instance->user_must_wait_to_join() || $meetinginfo->statusrunning; $canjoin = !$instance->user_must_wait_to_join() || $meetinginfo->statusrunning;
// Limit has not been reached or user does not count toward limit. // Limit has not been reached.
$canjoin = $canjoin && ( $canjoin = $canjoin && (!$instance->has_user_limit_been_reached($totalusercount));
!$instance->has_user_limit_been_reached($participantcount)
|| !$instance->does_current_user_count_towards_user_limit()
);
// User should only join during scheduled session start and end time, if defined. // User should only join during scheduled session start and end time, if defined.
$canjoin = $canjoin && ($instance->is_currently_open()); $canjoin = $canjoin && ($instance->is_currently_open());
// Double check that the user has the capabilities to join. // Double check that the user has the capabilities to join.
@ -286,7 +283,7 @@ class meeting {
$meetinginfo->startedat = floor(intval($info['startTime']) / 1000); // Milliseconds. $meetinginfo->startedat = floor(intval($info['startTime']) / 1000); // Milliseconds.
$meetinginfo->moderatorcount = $info['moderatorCount']; $meetinginfo->moderatorcount = $info['moderatorCount'];
$meetinginfo->moderatorplural = $info['moderatorCount'] > 1; $meetinginfo->moderatorplural = $info['moderatorCount'] > 1;
$meetinginfo->participantcount = $participantcount - $meetinginfo->moderatorcount; $meetinginfo->participantcount = $totalusercount - $meetinginfo->moderatorcount;
$meetinginfo->participantplural = $meetinginfo->participantcount > 1; $meetinginfo->participantplural = $meetinginfo->participantcount > 1;
} }
$meetinginfo->statusmessage = $this->get_status_message($meetinginfo, $instance); $meetinginfo->statusmessage = $this->get_status_message($meetinginfo, $instance);
@ -322,6 +319,9 @@ class meeting {
* @return string * @return string
*/ */
protected function get_status_message(object $meetinginfo, instance $instance): string { protected function get_status_message(object $meetinginfo, instance $instance): string {
if ($instance->has_user_limit_been_reached($meetinginfo->totalusercount)) {
return get_string('view_message_conference_user_limit_reached', 'bigbluebuttonbn');
}
if ($meetinginfo->statusrunning) { if ($meetinginfo->statusrunning) {
return get_string('view_message_conference_in_progress', 'bigbluebuttonbn'); return get_string('view_message_conference_in_progress', 'bigbluebuttonbn');
} }
@ -551,10 +551,7 @@ class meeting {
protected function prepare_meeting_join_action(int $origin) { protected function prepare_meeting_join_action(int $origin) {
$this->do_get_meeting_info(true); $this->do_get_meeting_info(true);
if ($this->is_running()) { if ($this->is_running()) {
if ( if ($this->instance->has_user_limit_been_reached($this->get_participant_count())) {
$this->instance->has_user_limit_been_reached($this->get_participant_count())
&& $this->instance->does_current_user_count_towards_user_limit()
) {
throw new meeting_join_exception('userlimitreached'); throw new meeting_join_exception('userlimitreached');
} }
} else if ($this->instance->user_must_wait_to_join()) { } else if ($this->instance->user_must_wait_to_join()) {

View file

@ -516,6 +516,7 @@ $string['view_message_conference_not_started'] = 'The session has not started ye
$string['view_message_conference_wait_for_moderator'] = 'Waiting for a moderator to join.'; $string['view_message_conference_wait_for_moderator'] = 'Waiting for a moderator to join.';
$string['view_message_conference_in_progress'] = 'The session is in progress.'; $string['view_message_conference_in_progress'] = 'The session is in progress.';
$string['view_message_conference_has_ended'] = 'The session has ended.'; $string['view_message_conference_has_ended'] = 'The session has ended.';
$string['view_message_conference_user_limit_reached'] = 'The number of users allowed in a session has been reached';
$string['view_message_tab_close'] = 'This tab/window must be closed manually'; $string['view_message_tab_close'] = 'This tab/window must be closed manually';
$string['view_message_recordings_disabled'] = 'Recordings are disabled on the server. BigBlueButton activities of type \'Recordings only\' cannot be used.'; $string['view_message_recordings_disabled'] = 'Recordings are disabled on the server. BigBlueButton activities of type \'Recordings only\' cannot be used.';
$string['view_message_cron_disabled'] = 'The list of recordings may not be up to date. Please contact the site administrator with the following information: {$a}'; $string['view_message_cron_disabled'] = 'The list of recordings may not be up to date. Please contact the site administrator with the following information: {$a}';

View file

@ -5,18 +5,21 @@ Feature: Test the ability to run the full meeting lifecycle (start to end)
Background: Background:
Given a BigBlueButton mock server is configured Given a BigBlueButton mock server is configured
And I enable "bigbluebuttonbn" "mod" plugin And I enable "bigbluebuttonbn" "mod" plugin
And the following config values are set as admin:
Scenario: Users should be able to join a meeting then end the meeting for themselves and | bigbluebuttonbn_userlimit_editable | 1 |
return to the meeting page to join again.
Given the following course exists: Given the following course exists:
| name | Test course | | name | Test course |
| shortname | C1 | | shortname | C1 |
And the following "users" exist: And the following "users" exist:
| username | firstname | lastname | email | | username | firstname | lastname | email |
| traverst | Terry | Travers | t.travers@example.com | | traverst | Terry | Travers | t.travers@example.com |
| uraverst | Uerry | Uravers | u.uravers@example.com |
| vraverst | Verry | Vravers | v.vravers@example.com |
And the following "course enrolments" exist: And the following "course enrolments" exist:
| user | course | role | | user | course | role |
| traverst | C1 | student | | traverst | C1 | student |
| uraverst | C1 | student |
| vraverst | C1 | student |
And the following "activity" exists: And the following "activity" exists:
| course | C1 | | course | C1 |
| activity | bigbluebuttonbn | | activity | bigbluebuttonbn |
@ -24,6 +27,10 @@ Feature: Test the ability to run the full meeting lifecycle (start to end)
| idnumber | Room recordings | | idnumber | Room recordings |
| moderators | role:editingteacher | | moderators | role:editingteacher |
| wait | 0 | | wait | 0 |
| userlimit | 2 |
Scenario: Users should be able to join a meeting then end the meeting for themselves and
return to the meeting page to join again.
When I am on the "Room recordings" Activity page logged in as traverst When I am on the "Room recordings" Activity page logged in as traverst
Then "Join session" "link" should exist Then "Join session" "link" should exist
When I click on "Join session" "link" When I click on "Join session" "link"
@ -37,3 +44,22 @@ Feature: Test the ability to run the full meeting lifecycle (start to end)
And I reload the page And I reload the page
Then I should see "Room recordings" Then I should see "Room recordings"
And I should see "This room is ready. You can join the session now." And I should see "This room is ready. You can join the session now."
Scenario: Users can join the meeting until the maximum number of users has been reached
When I am on the "Room recordings" Activity page logged in as traverst
Then "Join session" "link" should exist
And I click on "Join session" "link"
And I switch to the main window
And I log out
Then I am on the "Room recordings" Activity page logged in as uraverst
And "Join session" "link" should exist
And I click on "Join session" "link"
And I switch to the main window
And I log out
Then I am on the "Room recordings" Activity page logged in as vraverst
Then "Join session" "link" should not exist
And I should see "The number of users allowed in a session has been reached"
And I log out
Then I am on the "Room recordings" Activity page logged in as admin
Then "Join session" "link" should not exist
And I should see "The number of users allowed in a session has been reached"

View file

@ -301,6 +301,54 @@ class meeting_test extends \advanced_testcase {
$this->assertIsString($joinurl); $this->assertIsString($joinurl);
} }
/**
* Test can join is working if the "user limit" setting is set and reached.
*
* @covers ::join
* @covers ::join_meeting
*/
public function test_join_user_limit_reached() {
$this->resetAfterTest();
set_config('bigbluebuttonbn_userlimit_editable', true);
$this->setAdminUser();
$bbbgenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
$moderator = $this->getDataGenerator()->create_and_enrol($this->get_course(), 'editingteacher');
$student1 = $this->getDataGenerator()->create_and_enrol($this->get_course());
$student2 = $this->getDataGenerator()->create_and_enrol($this->get_course());
$meetinginfo = [
'course' => $this->get_course()->id,
'type' => instance::TYPE_ALL,
'userlimit' => 2,
];
$activity = $bbbgenerator->create_instance($meetinginfo, [
'userlimit' => 2,
]);
$instance = instance::get_from_instanceid($activity->id);
$meeting = new meeting($instance);
$bbbgenerator->create_meeting([
'instanceid' => $instance->get_instance_id(),
]);
// Moderator joins the meeting.
$this->setUser($moderator);
$this->join_meeting($meeting->join(logger::ORIGIN_BASE));
$meeting->update_cache();
$this->assertEquals(1, $meeting->get_participant_count());
// Student1 joins the meeting.
$this->setUser($student1);
$this->join_meeting($meeting->join(logger::ORIGIN_BASE));
$meeting->update_cache();
$this->assertEquals(2, $meeting->get_participant_count());
$this->assertTrue($instance->has_user_limit_been_reached($meeting->get_participant_count()));
// Student2 tries to join but the limit has been reached.
$this->setUser($student2);
$meeting->update_cache();
$this->assertFalse($meeting->can_join());
$this->expectException(\mod_bigbluebuttonbn\local\exceptions\meeting_join_exception::class);
meeting::join_meeting($instance);
}
/** /**
* Test that attendees returns the right list of attendees * Test that attendees returns the right list of attendees
* *
@ -336,18 +384,21 @@ class meeting_test extends \advanced_testcase {
$meeting->update_cache(); $meeting->update_cache();
$meetinginfo = $meeting->get_meeting_info(); $meetinginfo = $meeting->get_meeting_info();
$this->assertEquals(1, $meetinginfo->participantcount); $this->assertEquals(1, $meetinginfo->participantcount);
$this->assertEquals(1, $meetinginfo->totalusercount);
$this->assertEquals(0, $meetinginfo->moderatorcount); $this->assertEquals(0, $meetinginfo->moderatorcount);
$this->setUser($usernotingroup); $this->setUser($usernotingroup);
$this->join_meeting($meeting->join(logger::ORIGIN_BASE)); $this->join_meeting($meeting->join(logger::ORIGIN_BASE));
$meeting->update_cache(); $meeting->update_cache();
$meetinginfo = $meeting->get_meeting_info(); $meetinginfo = $meeting->get_meeting_info();
$this->assertEquals(2, $meetinginfo->participantcount); $this->assertEquals(2, $meetinginfo->participantcount);
$this->assertEquals(2, $meetinginfo->totalusercount);
$this->assertEquals(0, $meetinginfo->moderatorcount); $this->assertEquals(0, $meetinginfo->moderatorcount);
$this->setAdminUser(); $this->setAdminUser();
$this->join_meeting($meeting->join(logger::ORIGIN_BASE)); $this->join_meeting($meeting->join(logger::ORIGIN_BASE));
$meeting->update_cache(); $meeting->update_cache();
$meetinginfo = $meeting->get_meeting_info(); $meetinginfo = $meeting->get_meeting_info();
$this->assertEquals(2, $meetinginfo->participantcount); $this->assertEquals(2, $meetinginfo->participantcount);
$this->assertEquals(3, $meetinginfo->totalusercount);
$this->assertEquals(1, $meetinginfo->moderatorcount); $this->assertEquals(1, $meetinginfo->moderatorcount);
} }
/** /**