From b924f6a3558fd0efebe68b87a8475061e113e9ec Mon Sep 17 00:00:00 2001 From: "Shamiso.Jaravaza" <33659194+ssj365@users.noreply.github.com> Date: Fri, 10 Mar 2023 11:21:34 -0700 Subject: [PATCH] MDL-76303 mod_bigbluebuttonbn: Fix userlimit --- mod/bigbluebuttonbn/classes/meeting.php | 27 +++++----- .../lang/en/bigbluebuttonbn.php | 1 + .../tests/behat/join_meeting.feature | 34 +++++++++++-- mod/bigbluebuttonbn/tests/meeting_test.php | 51 +++++++++++++++++++ 4 files changed, 94 insertions(+), 19 deletions(-) diff --git a/mod/bigbluebuttonbn/classes/meeting.php b/mod/bigbluebuttonbn/classes/meeting.php index 6a13df20b45..d61c3487b6a 100644 --- a/mod/bigbluebuttonbn/classes/meeting.php +++ b/mod/bigbluebuttonbn/classes/meeting.php @@ -147,12 +147,12 @@ class meeting { } /** - * Number of participants + * Total number of moderators and viewers. * * @return int */ 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); // 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. - $participantcount = 0; + $totalusercount = 0; // This is the default value for any meeting that has not been created. $meetinginfo->statusrunning = false; $meetinginfo->createtime = null; @@ -262,19 +262,16 @@ class meeting { if (!empty($info)) { $meetinginfo->statusrunning = $info['running'] === 'true'; $meetinginfo->createtime = $info['createTime'] ?? null; - $participantcount = isset($info['participantCount']) ? $info['participantCount'] : 0; + $totalusercount = isset($info['participantCount']) ? $info['participantCount'] : 0; } $meetinginfo->statusclosed = $activitystatus === 'ended'; $meetinginfo->statusopen = !$meetinginfo->statusrunning && $activitystatus === 'open'; - $meetinginfo->participantcount = $participantcount; + $meetinginfo->totalusercount = $totalusercount; $canjoin = !$instance->user_must_wait_to_join() || $meetinginfo->statusrunning; - // Limit has not been reached or user does not count toward limit. - $canjoin = $canjoin && ( - !$instance->has_user_limit_been_reached($participantcount) - || !$instance->does_current_user_count_towards_user_limit() - ); + // Limit has not been reached. + $canjoin = $canjoin && (!$instance->has_user_limit_been_reached($totalusercount)); // User should only join during scheduled session start and end time, if defined. $canjoin = $canjoin && ($instance->is_currently_open()); // 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->moderatorcount = $info['moderatorCount']; $meetinginfo->moderatorplural = $info['moderatorCount'] > 1; - $meetinginfo->participantcount = $participantcount - $meetinginfo->moderatorcount; + $meetinginfo->participantcount = $totalusercount - $meetinginfo->moderatorcount; $meetinginfo->participantplural = $meetinginfo->participantcount > 1; } $meetinginfo->statusmessage = $this->get_status_message($meetinginfo, $instance); @@ -322,6 +319,9 @@ class meeting { * @return 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) { return get_string('view_message_conference_in_progress', 'bigbluebuttonbn'); } @@ -551,10 +551,7 @@ class meeting { protected function prepare_meeting_join_action(int $origin) { $this->do_get_meeting_info(true); if ($this->is_running()) { - if ( - $this->instance->has_user_limit_been_reached($this->get_participant_count()) - && $this->instance->does_current_user_count_towards_user_limit() - ) { + if ($this->instance->has_user_limit_been_reached($this->get_participant_count())) { throw new meeting_join_exception('userlimitreached'); } } else if ($this->instance->user_must_wait_to_join()) { diff --git a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php index eb8311b60d5..7f4ad601c80 100644 --- a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php +++ b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php @@ -513,6 +513,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_in_progress'] = 'The session is in progress.'; $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_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}'; diff --git a/mod/bigbluebuttonbn/tests/behat/join_meeting.feature b/mod/bigbluebuttonbn/tests/behat/join_meeting.feature index 8516ed1ec17..a9c45254026 100644 --- a/mod/bigbluebuttonbn/tests/behat/join_meeting.feature +++ b/mod/bigbluebuttonbn/tests/behat/join_meeting.feature @@ -5,18 +5,21 @@ Feature: Test the ability to run the full meeting lifecycle (start to end) Background: Given a BigBlueButton mock server is configured And I enable "bigbluebuttonbn" "mod" plugin - - Scenario: Users should be able to join a meeting then end the meeting for themselves and - return to the meeting page to join again. + And the following config values are set as admin: + | bigbluebuttonbn_userlimit_editable | 1 | Given the following course exists: | name | Test course | | shortname | C1 | And the following "users" exist: | username | firstname | lastname | email | | 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: - | user | course | role | + | user | course | role | | traverst | C1 | student | + | uraverst | C1 | student | + | vraverst | C1 | student | And the following "activity" exists: | course | C1 | | activity | bigbluebuttonbn | @@ -24,6 +27,10 @@ Feature: Test the ability to run the full meeting lifecycle (start to end) | idnumber | Room recordings | | moderators | role:editingteacher | | 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 Then "Join session" "link" should exist 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 Then I should see "Room recordings" 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" diff --git a/mod/bigbluebuttonbn/tests/meeting_test.php b/mod/bigbluebuttonbn/tests/meeting_test.php index 7e3bde54ea6..d19dd8618d7 100644 --- a/mod/bigbluebuttonbn/tests/meeting_test.php +++ b/mod/bigbluebuttonbn/tests/meeting_test.php @@ -301,6 +301,54 @@ class meeting_test extends \advanced_testcase { $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 * @@ -336,18 +384,21 @@ class meeting_test extends \advanced_testcase { $meeting->update_cache(); $meetinginfo = $meeting->get_meeting_info(); $this->assertEquals(1, $meetinginfo->participantcount); + $this->assertEquals(1, $meetinginfo->totalusercount); $this->assertEquals(0, $meetinginfo->moderatorcount); $this->setUser($usernotingroup); $this->join_meeting($meeting->join(logger::ORIGIN_BASE)); $meeting->update_cache(); $meetinginfo = $meeting->get_meeting_info(); $this->assertEquals(2, $meetinginfo->participantcount); + $this->assertEquals(2, $meetinginfo->totalusercount); $this->assertEquals(0, $meetinginfo->moderatorcount); $this->setAdminUser(); $this->join_meeting($meeting->join(logger::ORIGIN_BASE)); $meeting->update_cache(); $meetinginfo = $meeting->get_meeting_info(); $this->assertEquals(2, $meetinginfo->participantcount); + $this->assertEquals(3, $meetinginfo->totalusercount); $this->assertEquals(1, $meetinginfo->moderatorcount); } /**