From 27f8796c22b56c9dc98ec638aad7ca9fe7208351 Mon Sep 17 00:00:00 2001 From: Laurent David Date: Fri, 31 Mar 2023 11:20:36 +0200 Subject: [PATCH] MDL-77660 mod_bigbluebuttonbn: Add completion for subplugins * Add callback to the mod edit form * Refactor completion class to use addons * Add new behat and phpunit tests --- .../classes/completion/custom_completion.php | 54 ++++++-- mod/bigbluebuttonbn/classes/extension.php | 23 ++++ .../extension/custom_completion_addons.php | 78 ++++++++++++ .../local/plugins/admin_plugin_manager.php | 2 + .../classes/local/proxy/recording_proxy.php | 2 +- .../tests/behat/edit_instance.feature | 10 +- .../tests/behat/subplugins.feature | 50 +++++++- .../tests/completion/completion_test.php | 1 - .../custom_completion_addons.php | 82 ++++++++++++ .../bigbluebuttonbn/mod_form_addons.php | 13 +- .../bigbluebuttonbn/mod_instance_helper.php | 5 +- .../fixtures/extension/simple/db/install.xml | 1 + .../simple/lang/en/bbbext_simple.php | 3 + .../tests/local/extension_test.php | 118 +++++++++++++++++- 14 files changed, 411 insertions(+), 31 deletions(-) create mode 100644 mod/bigbluebuttonbn/classes/local/extension/custom_completion_addons.php create mode 100644 mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/custom_completion_addons.php diff --git a/mod/bigbluebuttonbn/classes/completion/custom_completion.php b/mod/bigbluebuttonbn/classes/completion/custom_completion.php index 3de9569e87d..5bbe81bcc14 100644 --- a/mod/bigbluebuttonbn/classes/completion/custom_completion.php +++ b/mod/bigbluebuttonbn/classes/completion/custom_completion.php @@ -16,7 +16,9 @@ namespace mod_bigbluebuttonbn\completion; +use cm_info; use core_completion\activity_custom_completion; +use mod_bigbluebuttonbn\extension; use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\logger; use moodle_exception; @@ -43,6 +45,25 @@ class custom_completion extends activity_custom_completion { 'completionengagementpollvotes' => [logger::EVENT_SUMMARY], 'completionengagementemojis' => [logger::EVENT_SUMMARY], ]; + /** + * @var array $completionaddons array of extension class for the completion + */ + private $completionaddons; + + /** + * activity_custom_completion constructor. + * + * @param cm_info $cm + * @param int $userid + * @param array|null $completionstate The current state of the core completion criteria + */ + public function __construct(cm_info $cm, int $userid, ?array $completionstate = null) { + parent::__construct($cm, $userid, $completionstate); + $completionaddonsclasses = extension::custom_completion_addons_instances($cm, $userid, $completionstate); + $this->completionaddons = array_map(function($targetclassname) use ($cm, $userid, $completionstate) { + return new $targetclassname($cm, $userid, $completionstate); + }, $completionaddonsclasses); + } /** * Get current state @@ -79,6 +100,12 @@ class custom_completion extends activity_custom_completion { } } } + // Check for any completion for this rule in addons / extensions. + foreach ($this->completionaddons as $customcompletion) { + if (in_array($rule, $customcompletion->get_defined_custom_rules())) { + $returnedvalue = $returnedvalue || $customcompletion->get_state($rule); + } + } return $returnedvalue; } @@ -102,14 +129,13 @@ class custom_completion extends activity_custom_completion { return $value; } - /** * Fetch the list of custom completion rules that this module defines. * * @return array */ public static function get_defined_custom_rules(): array { - return [ + $rules = [ 'completionattendance', 'completionengagementchats', 'completionengagementtalks', @@ -117,6 +143,11 @@ class custom_completion extends activity_custom_completion { 'completionengagementpollvotes', 'completionengagementemojis', ]; + $completionaddonsclasses = extension::custom_completion_addons_classes(); + foreach ($completionaddonsclasses as $customcompletion) { + $rules = array_merge($rules, $customcompletion::get_defined_custom_rules()); + } + return $rules; } /** @@ -131,7 +162,7 @@ class custom_completion extends activity_custom_completion { $completionengagementpollvotes = $this->cm->customdata['customcompletionrules']['completionengagementpollvotes'] ?? 1; $completionengagementemojis = $this->cm->customdata['customcompletionrules']['completionengagementemojis'] ?? 1; $completionattendance = $this->cm->customdata['customcompletionrules']['completionattendance'] ?? 1; - return [ + $descriptions = [ 'completionengagementchats' => get_string('completionengagementchats_desc', 'mod_bigbluebuttonbn', $completionengagementchats), 'completionengagementtalks' => get_string('completionengagementtalks_desc', 'mod_bigbluebuttonbn', @@ -145,6 +176,11 @@ class custom_completion extends activity_custom_completion { 'completionattendance' => get_string('completionattendance_desc', 'mod_bigbluebuttonbn', $completionattendance), ]; + // Check for any completion for this rule in addons / extensions. + foreach ($this->completionaddons as $customcompletion) { + $descriptions = array_merge($descriptions, $customcompletion->get_custom_rule_descriptions()); + } + return $descriptions; } /** @@ -153,15 +189,9 @@ class custom_completion extends activity_custom_completion { * @return array */ public function get_sort_order(): array { - return [ - 'completionview', - 'completionengagementchats', - 'completionengagementtalks', - 'completionengagementraisehand', - 'completionengagementpollvotes', - 'completionengagementemojis', - 'completionattendance', - ]; + $rules = self::get_defined_custom_rules(); + array_unshift($rules, 'completionview'); + return $rules; } /** diff --git a/mod/bigbluebuttonbn/classes/extension.php b/mod/bigbluebuttonbn/classes/extension.php index 3162b43426e..b17bcc12e59 100644 --- a/mod/bigbluebuttonbn/classes/extension.php +++ b/mod/bigbluebuttonbn/classes/extension.php @@ -16,7 +16,9 @@ namespace mod_bigbluebuttonbn; use cache; +use cm_info; use mod_bigbluebuttonbn\local\extension\action_url_addons; +use mod_bigbluebuttonbn\local\extension\custom_completion_addons; use mod_bigbluebuttonbn\local\extension\mod_form_addons; use mod_bigbluebuttonbn\local\extension\mod_instance_helper; use stdClass; @@ -114,6 +116,27 @@ class extension { return $extensionclasses; } + /** + * Get all custom_completion addons classes. + * + * @return array of custom completion addon classes. + */ + public static function custom_completion_addons_classes(): array { + return self::get_classes_implementing(custom_completion_addons::class); + } + + /** + * Get all custom_completion addons classes instances. + * + * @param cm_info $cm + * @param int $userid + * @param array|null $completionstate + * @return array of custom completion addon instances. + */ + public static function custom_completion_addons_instances(cm_info $cm, int $userid, ?array $completionstate = null): array { + return self::get_instances_implementing(custom_completion_addons::class, [$cm, $userid, $completionstate]); + } + /** * Get all mod_form addons classes instances * diff --git a/mod/bigbluebuttonbn/classes/local/extension/custom_completion_addons.php b/mod/bigbluebuttonbn/classes/local/extension/custom_completion_addons.php new file mode 100644 index 00000000000..68d3588de02 --- /dev/null +++ b/mod/bigbluebuttonbn/classes/local/extension/custom_completion_addons.php @@ -0,0 +1,78 @@ +. +namespace mod_bigbluebuttonbn\local\extension; + +use cm_info; + +/** + * A class to deal with completion rules addons in a subplugin + * + * @package mod_bigbluebuttonbn + * @copyright 2023 onwards, Blindside Networks Inc + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Laurent David (laurent@call-learning.fr) + */ +abstract class custom_completion_addons { + /** @var cm_info The course module information object. */ + protected $cm; + + /** @var int The user's ID. */ + protected $userid; + + /** @var array The current state of core completion */ + protected $completionstate; + + /** + * activity_custom_completion constructor. + * + * @param cm_info $cm + * @param int $userid + * @param array|null $completionstate The current state of the core completion criteria + */ + public function __construct(cm_info $cm, int $userid, ?array $completionstate = null) { + $this->cm = $cm; + $this->userid = $userid; + $this->completionstate = $completionstate; + } + /** + * Fetches the completion state for a given completion rule. + * + * @param string $rule The completion rule. + * @return int The completion state. + */ + abstract public function get_state(string $rule): int; + + /** + * Fetch the list of custom completion rules that this module defines. + * + * @return array + */ + abstract public static function get_defined_custom_rules(): array; + + /** + * Returns an associative array of the descriptions of custom completion rules. + * + * @return array + */ + abstract public function get_custom_rule_descriptions(): array; + + /** + * Returns an array of all completion rules, in the order they should be displayed to users. + * + * @return array + */ + abstract public function get_sort_order(): array; +} diff --git a/mod/bigbluebuttonbn/classes/local/plugins/admin_plugin_manager.php b/mod/bigbluebuttonbn/classes/local/plugins/admin_plugin_manager.php index ad752446e68..5c4be21dfb5 100644 --- a/mod/bigbluebuttonbn/classes/local/plugins/admin_plugin_manager.php +++ b/mod/bigbluebuttonbn/classes/local/plugins/admin_plugin_manager.php @@ -251,6 +251,8 @@ class admin_plugin_manager { $class = \core_plugin_manager::resolve_plugininfo_class(extension::BBB_EXTENSION_PLUGIN_NAME); $class::enable_plugin($plugin, false); cache_helper::purge_by_event('mod_bigbluebuttonbn/pluginenabledisabled'); + // Also clear the cache for all BigBlueButtonModules. + rebuild_course_cache(0, true); return 'view'; } diff --git a/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php b/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php index f3df3de5d11..777f277badd 100644 --- a/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php +++ b/mod/bigbluebuttonbn/classes/local/proxy/recording_proxy.php @@ -49,7 +49,7 @@ class recording_proxy extends proxy_base { * @param string $recordid a recording id * @return bool */ - public static function delete_recording(string $recordid, ?int $instanceid = null): bool { + public static function delete_recording(string $recordid): bool { $result = self::fetch_endpoint_xml('deleteRecordings', ['recordID' => $recordid]); if (!$result || $result->returncode != 'SUCCESS') { return false; diff --git a/mod/bigbluebuttonbn/tests/behat/edit_instance.feature b/mod/bigbluebuttonbn/tests/behat/edit_instance.feature index 2725e896182..5b5d42a1a2f 100644 --- a/mod/bigbluebuttonbn/tests/behat/edit_instance.feature +++ b/mod/bigbluebuttonbn/tests/behat/edit_instance.feature @@ -37,15 +37,15 @@ Feature: I can edit a bigbluebutton instance | bigbluebuttonbn_meetingevents_enabled | 1 | And the following "users" exist: | username | firstname | lastname | - | student1 | Student1 | 1 | + | student1 | Student1 | 1 | And the following "course enrolments" exist: - | user | course | role | + | user | course | role | | student1 | Test course | student | And I am on the "RoomRecordings" "bigbluebuttonbn activity editing" page logged in as "admin" And I expand all fieldsets And I set the following fields to these values: - | Completion tracking | Show activity as complete when conditions are met | - | Require view | 1 | + | Add requirements | 1 | + | View the activity | 1 | And I press "Save and return to course" And I log out # Then I visit the page first to make sure that completion settings are locked. @@ -54,6 +54,6 @@ Feature: I can edit a bigbluebutton instance And I am on the "RoomRecordings" "bigbluebuttonbn activity editing" page logged in as "admin" When I expand all fieldsets Then I should see "Completion options locked" - And the "Require view" "field" should be disabled + And the "View the activity" "field" should be disabled And the "completionattendanceenabled" "field" should be disabled And the "Chats" "field" should be disabled diff --git a/mod/bigbluebuttonbn/tests/behat/subplugins.feature b/mod/bigbluebuttonbn/tests/behat/subplugins.feature index 9a0dab11973..ede760905f5 100644 --- a/mod/bigbluebuttonbn/tests/behat/subplugins.feature +++ b/mod/bigbluebuttonbn/tests/behat/subplugins.feature @@ -3,14 +3,15 @@ Feature: BigBlueButtonBN Subplugins test As a BigBlueButtonBN user I can list the subplugins the admin settings pages I can see the additional settings coming from the subplugins in the edit form + Background: Make sure that the BigBlueButtonBN plugin is enabled Given I accept dpa and enable bigbluebuttonbn plugin And the following "courses" exist: - | fullname | shortname | category | - | Test course | Test course | 0 | + | fullname | shortname | category | enablecompletion | + | Test course | Test course | 0 | 1 | And the following "activities" exist: - | activity | course | name | type | - | bigbluebuttonbn | Test course | BBB Instance name | 0 | + | activity | course | name | type | + | bigbluebuttonbn | Test course | BBB Instance name | 0 | Scenario: Add a subplugin and check that the settings are available Given I log in as "admin" @@ -43,3 +44,44 @@ Feature: BigBlueButtonBN Subplugins test And I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page When I expand all fieldsets Then I should not see "New field" + + @javascript + Scenario: I check that custom completion with subplugin works + Given a BigBlueButton mock server is configured + And the following config values are set as admin: + | bigbluebuttonbn_meetingevents_enabled | 1 | + And the following "users" exist: + | username | firstname | lastname | email | + | traverst | Terry | Travers | t.travers@example.com | + And the following "course enrolments" exist: + | user | course | role | + | traverst | Test course | student | + And I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page logged in as "admin" + And I expand all fieldsets + And I set the following fields to these values: + | Add requirements | 1 | + | Raise hand twice | 1 | + And I set the field "New field" to "50" + And I press "Save and display" + # We start the meeting here so to make sure that meta_analytics-callback-url is set. + And the following "mod_bigbluebuttonbn > meeting" exists: + | activity | BBB Instance name | + And I log out + And I am on the "BBB Instance name" "bigbluebuttonbn activity" page logged in as "traverst" + And I click on "Join session" "link" + And I switch to "bigbluebutton_conference" window + And I wait until the page is ready + And I follow "End Meeting" + And the BigBlueButtonBN server has received the following events from user "traverst": + | instancename | eventtype | eventdata | + | BBB Instance name | raisehand | 1 | + | BBB Instance name | raisehand | 1 | + # Selenium driver does not like the click action to be done before we + # automatically close the window so we need to make sure that the window + # is closed before. + And I close all opened windows + And I switch to the main window + And the BigBlueButtonBN activity "BBB Instance name" has sent recording all its events + And I run all adhoc tasks + When I reload the page + Then I should see "Done: Raise hand twice in a meeting." diff --git a/mod/bigbluebuttonbn/tests/completion/completion_test.php b/mod/bigbluebuttonbn/tests/completion/completion_test.php index 4870447881e..99ce8697901 100644 --- a/mod/bigbluebuttonbn/tests/completion/completion_test.php +++ b/mod/bigbluebuttonbn/tests/completion/completion_test.php @@ -19,7 +19,6 @@ namespace mod_bigbluebuttonbn\completion; use completion_info; use context_module; use mod_bigbluebuttonbn\instance; -use mod_bigbluebuttonbn\local\config; use mod_bigbluebuttonbn\logger; use mod_bigbluebuttonbn\meeting; use mod_bigbluebuttonbn\test\testcase_helper_trait; diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/custom_completion_addons.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/custom_completion_addons.php new file mode 100644 index 00000000000..a5edba0019c --- /dev/null +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/custom_completion_addons.php @@ -0,0 +1,82 @@ +. +namespace bbbext_simple\bigbluebuttonbn; + +use mod_bigbluebuttonbn\instance; +use mod_bigbluebuttonbn\logger; + +/** + * A class to deal with completion rules addons in a subplugin + * + * @package mod_bigbluebuttonbn + * @copyright 2023 onwards, Blindside Networks Inc + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Laurent David (laurent@call-learning.fr) + */ +class custom_completion_addons extends \mod_bigbluebuttonbn\local\extension\custom_completion_addons { + + /** + * Get defined custom rule + * + * @return string[] + */ + public static function get_defined_custom_rules(): array { + return ['completionextraisehandtwice']; + } + + /** + * Get state + * + * @param string $rule + * @return int + */ + public function get_state(string $rule): int { + $instance = instance::get_from_cmid($this->cm->id); + $logs = logger::get_user_completion_logs($instance, $this->userid, [logger::EVENT_SUMMARY]); + $raisehandcount = 0; + foreach ($logs as $log) { + $summary = json_decode($log->meta); + $raisehandcount += intval($summary->data->engagement->raisehand ?? 0); + } + if ($raisehandcount >= 2) { + return COMPLETION_COMPLETE; + } + return COMPLETION_INCOMPLETE; + } + + /** + * Get rule description + * + * @return array + * @throws \coding_exception + */ + public function get_custom_rule_descriptions(): array { + return [ + 'completionextraisehandtwice' => get_string('completionextraisehandtwice_desc', 'bbbext_simple'), + ]; + } + + /** + * Get sort order + * + * @return string[] + */ + public function get_sort_order(): array { + return [ + 'completionattendance', + ]; + } +} diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php index e9dd30d760b..bd7e0155dcc 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php @@ -69,7 +69,14 @@ class mod_form_addons extends \mod_bigbluebuttonbn\local\extension\mod_form_addo * @return array Array of string IDs of added items, empty array if none */ public function add_completion_rules(): array { - return []; + $this->mform->addElement('advcheckbox', 'completionextraisehandtwice', + get_string('completionextraisehandtwice', 'bbbext_simple'), + get_string('completionextraisehandtwice_desc', 'bbbext_simple')); + + $this->mform->addHelpButton('completionextraisehandtwice', 'completionextraisehandtwice', + 'bbbext_simple'); + $this->mform->disabledIf('completionextraisehandtwice', 'completion', 'neq', COMPLETION_AGGREGATION_ANY); + return ['completionextraisehandtwice' . $this->suffix]; } /** @@ -81,7 +88,7 @@ class mod_form_addons extends \mod_bigbluebuttonbn\local\extension\mod_form_addo * default returns false */ public function completion_rule_enabled(array $data): bool { - return false; + return !empty($data['completionextraisehandtwice' . $this->suffix]); } /** @@ -111,7 +118,7 @@ class mod_form_addons extends \mod_bigbluebuttonbn\local\extension\mod_form_addo */ public function validation(array $data, array $files): array { $errors = []; - if (empty($data['newfield'])) { + if (empty($data['newfield' . $this->suffix])) { $errors['newfield'] = get_string('newfielderror', 'bbbext_simple'); } return $errors; diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php index 813996a66be..86e0bcd32a3 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php @@ -35,7 +35,8 @@ class mod_instance_helper extends \mod_bigbluebuttonbn\local\extension\mod_insta global $DB; $DB->insert_record('bbbext_simple', (object) [ 'bigbluebuttonbnid' => $bigbluebuttonbn->id, - 'newfield' => $bigbluebuttonbn->newfield ?? '' + 'newfield' => $bigbluebuttonbn->newfield ?? '', + 'completionextraisehandtwice' => $bigbluebuttonbn->completionextraisehandtwice ?? '', ]); } @@ -54,9 +55,11 @@ class mod_instance_helper extends \mod_bigbluebuttonbn\local\extension\mod_insta $record = new stdClass(); $record->bigbluebuttonbnid = $bigbluebuttonbn->id; $record->newfield = $bigbluebuttonbn->newfield ?? ''; + $record->completionextraisehandtwice = $bigbluebuttonbn->completionextraisehandtwice ?? 0; $DB->insert_record('bbbext_simple', $record); } else { $record->newfield = $bigbluebuttonbn->newfield ?? ''; + $record->completionextraisehandtwice = $bigbluebuttonbn->completionextraisehandtwice ?? 0; $DB->update_record('bbbext_simple', $record); } } diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/db/install.xml b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/db/install.xml index 27be9232c30..253d9b8281b 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/db/install.xml +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/db/install.xml @@ -9,6 +9,7 @@ + diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php index 41f55b72143..fc3b2dbb21a 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php @@ -27,3 +27,6 @@ $string['config_extension'] = 'Sample config extension setting'; $string['newfield'] = 'New field'; $string['newfielderror'] = 'New field cannot be empty'; $string['pluginname'] = 'Simple BigBlueButtonPlugin'; +$string['completionextraisehandtwice'] = 'Raise hand twice'; +$string['completionextraisehandtwice_desc'] = 'Raise hand twice in a meeting.'; +$string['completionextraisehandtwice_help'] = 'Raise hand twice in a meeting.'; diff --git a/mod/bigbluebuttonbn/tests/local/extension_test.php b/mod/bigbluebuttonbn/tests/local/extension_test.php index be907af02a9..51d5460f111 100644 --- a/mod/bigbluebuttonbn/tests/local/extension_test.php +++ b/mod/bigbluebuttonbn/tests/local/extension_test.php @@ -17,6 +17,7 @@ namespace mod_bigbluebuttonbn\local; use backup; use backup_controller; +use mod_bigbluebuttonbn\completion\custom_completion; use mod_bigbluebuttonbn\extension; use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\local\extension\mod_instance_helper; @@ -258,6 +259,115 @@ class extension_test extends \advanced_testcase { $this->assertEquals(5, $oldfieldrecord->newfield); } + /** + * Test completion with and without addons. + * + * @param array $customcompletionrules + * @param array $events + * @param int $expectedstate + * @return void + * @dataProvider custom_completion_data_provider + * @covers \mod_bigbluebuttonbn\local\extension\custom_completion_addons + */ + public function test_additional_completion(array $customcompletionrules, array $events, int $expectedstate): void { + // Enable plugin. + $this->enable_plugins(true); + $this->initialise_mock_server(); + list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance( + $this->get_course(), + array_merge([ + 'completion' => '2', + ], $customcompletionrules) + ); + + $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn'); + + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + + // Now create a couple of events. + $instance = instance::get_from_instanceid($bbactivity->id); + set_config('bigbluebuttonbn_meetingevents_enabled', true); + $meeting = $plugingenerator->create_meeting([ + 'instanceid' => $instance->get_instance_id(), + 'groupid' => $instance->get_group_id(), + 'participants' => json_encode([$user->id]), + ]); + foreach ($events as $edesc) { + $plugingenerator->add_meeting_event($user, $instance, $edesc->name, $edesc->data ?? ''); + } + $result = $plugingenerator->send_all_events($instance); + $this->assertNotEmpty($result->data); + $data = json_decode(json_encode($result->data)); + meeting::meeting_events($instance, $data); + $completion = new custom_completion($bbactivitycm, $user->id); + $result = $completion->get_overall_completion_state(); + $this->assertEquals($expectedstate, $result); + + } + + /** + * Data generator + * + * @return array[] + */ + public static function custom_completion_data_provider(): array { + global $CFG; + require_once($CFG->libdir . '/completionlib.php'); + return [ + 'simple' => [ + 'customcompletionrules' => [ + 'completionengagementtalks' => 1, + 'completionextraisehandtwice' => 1, + ], + 'events' => [ + (object) ['name' => 'talks'], + (object) ['name' => 'raisehand'], + (object) ['name' => 'raisehand'], + ], + 'expectedstate' => COMPLETION_COMPLETE, + ], + 'not right events' => [ + 'customcompletionrules' => [ + 'completionextraisehandtwice' => 1, + ], + 'events' => [ + (object) ['name' => 'chats'], + ], + 'expectedstate' => COMPLETION_INCOMPLETE, + ], + 'not enough events' => [ + 'customcompletionrules' => [ + 'completionextraisehandtwice' => 1, + ], + 'events' => [ + (object) ['name' => 'raisehand'], + ], + 'expectedstate' => COMPLETION_INCOMPLETE, + ], + 'more events' => [ + 'customcompletionrules' => [ + 'completionengagementtalks' => 1, + ], + 'events' => [ + (object) ['name' => 'talks'], + (object) ['name' => 'talks'], + (object) ['name' => 'talks'], + ], + 'expectedstate' => COMPLETION_COMPLETE, + ], + 'basics are still working' => [ + 'customcompletionrules' => [ + 'completionengagementtalks' => 1, + ], + 'events' => [ + (object) ['name' => 'talks'], + ], + 'expectedstate' => COMPLETION_COMPLETE, + ], + ]; + } + /** * Data provider for testing get_class_implementing * @@ -268,15 +378,15 @@ class extension_test extends \advanced_testcase { 'mod_instance_helper with plugin disabled' => [ 'bbbenabled' => false, 'apiclass' => mod_instance_helper::class, - 'result' => [] + 'result' => [], ], 'mod_instance_helper with plugin enabled' => [ 'bbbenabled' => true, 'apiclass' => mod_instance_helper::class, 'result' => [ - 'bbbext_simple\\bigbluebuttonbn\\mod_instance_helper' - ] - ] + 'bbbext_simple\\bigbluebuttonbn\\mod_instance_helper', + ], + ], ]; }