Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
namespace mod_bigbluebuttonbn\local;
17
 
18
use backup;
19
use backup_controller;
1441 ariadna 20
use mod_bigbluebuttonbn\broker;
1 efrain 21
use mod_bigbluebuttonbn\completion\custom_completion;
22
use mod_bigbluebuttonbn\extension;
23
use mod_bigbluebuttonbn\instance;
24
use mod_bigbluebuttonbn\local\extension\mod_instance_helper;
25
use mod_bigbluebuttonbn\meeting;
26
use mod_bigbluebuttonbn\test\subplugins_test_helper_trait;
27
use mod_bigbluebuttonbn\test\testcase_helper_trait;
28
use restore_controller;
29
use restore_dbops;
30
 
31
/**
32
 * Extension helper class test
33
 *
34
 * @package   mod_bigbluebuttonbn
35
 * @copyright 2023 - present, Blindside Networks Inc
36
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 * @author    Laurent David (laurent@call-learning.fr)
38
 * @coversDefaultClass \mod_bigbluebuttonbn\extension
39
 */
1441 ariadna 40
final class extension_test extends \advanced_testcase {
1 efrain 41
    use subplugins_test_helper_trait;
42
    use testcase_helper_trait;
43
 
44
    /**
45
     * Setup our fake plugin
46
     *
47
     * @return void
48
     */
49
    public function setUp(): void {
1441 ariadna 50
        parent::setUp();
1 efrain 51
        $this->resetAfterTest(true);
52
        $this->setup_fake_plugin('simple');
53
        $this->resetDebugging(); // We might have debugging messages issued from setup_fake_plugin here that we need to get rid of.
54
    }
55
 
56
 
57
    /**
58
     * Setup our fake plugin
59
     *
60
     * @return void
61
     */
62
    public function tearDown(): void {
63
        $this->uninstall_fake_plugin('simple');
1441 ariadna 64
        parent::tearDown();
1 efrain 65
    }
66
 
67
    /**
68
     * Test for the type_text provider.
69
     *
70
     * @param bool $bbbenabled
71
     * @param string $apiclass
72
     * @param array $extensionclasses
73
     *
74
     * @dataProvider classes_implementing_class
75
     * @covers       \mod_bigbluebuttonbn\extension::get_instances_implementing
76
     */
77
    public function test_get_class_implementing(bool $bbbenabled, string $apiclass, array $extensionclasses): void {
78
        $this->enable_plugins($bbbenabled);
79
        // Make the method public so we can test it.
80
        $reflectionextension = new \ReflectionClass(extension::class);
81
        $getclassimplementing = $reflectionextension->getMethod('get_instances_implementing');
82
        $allfoundinstances = $getclassimplementing->invoke(null, $apiclass);
83
        $foundclasses = array_map(
84
            function($instance) {
85
                return get_class($instance);
86
            },
87
            $allfoundinstances
88
        );
89
        $this->assertEquals($extensionclasses, $foundclasses);
90
    }
91
 
92
    /**
93
     * Test the add module callback
94
     *
95
     * @return void
96
     * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
97
     */
11 efrain 98
    public function test_mod_instance_helper_add(): void {
1 efrain 99
        global $DB;
100
        // Enable plugin.
101
        $this->enable_plugins(true);
102
 
103
        $course = $this->getDataGenerator()->create_course();
104
        $record = $this->getDataGenerator()->create_module(
105
            'bigbluebuttonbn',
106
            ['course' => $course->id, 'newfield' => 2]
107
        );
108
        $this->assertEquals(2, $DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
109
    }
110
 
111
    /**
112
     * Test the update module callback
113
     *
114
     * @return void
115
     * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
116
     */
11 efrain 117
    public function test_mod_instance_helper_update(): void {
1 efrain 118
        global $DB;
119
        $this->setAdminUser();
120
        // Enable plugin.
121
        $this->enable_plugins(true);
122
 
123
        $course = $this->getDataGenerator()->create_course();
124
        $record = $this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course->id, 'newfield' => 2]);
125
        $cm = get_fast_modinfo($course)->instances['bigbluebuttonbn'][$record->id];
126
        [$cm, $context, $moduleinfo, $data] = get_moduleinfo_data($cm, $course);
127
        $data->newfield = 3;
128
        bigbluebuttonbn_update_instance($data);
129
        $this->assertEquals(3, $DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
130
    }
131
 
132
    /**
133
     * Test delete module callback
134
     *
135
     * @return void
136
     * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper
137
     */
11 efrain 138
    public function test_mod_instance_helper_delete(): void {
1 efrain 139
        global $DB;
140
        $this->initialise_mock_server();
141
        // Enable plugin.
142
        $this->enable_plugins(true);
143
 
144
        $course = $this->getDataGenerator()->create_course();
145
        $record = $this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course->id, 'newfield' => 2]);
146
        $cm = get_fast_modinfo($course)->instances['bigbluebuttonbn'][$record->id];
147
        course_delete_module($cm->id, false);
148
        $this->assertFalse($DB->get_field('bbbext_simple', 'newfield', ['bigbluebuttonbnid' => $record->id]));
149
    }
150
 
151
    /**
152
     * Test the action_url_addons with plugin enabled
153
     *
154
     * @return void
155
     * @covers \mod_bigbluebuttonbn\extension::action_url_addons
156
     */
11 efrain 157
    public function test_action_url_addons(): void {
1 efrain 158
        // Enable plugin.
159
        $this->enable_plugins(true);
160
        $course = $this->get_course();
161
        [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
162
        $bbactivity->newfield = 4;
163
        extension::update_instance($bbactivity);
164
        ['data' => $additionalvar1, 'metadata' => $additionalvar2] =
165
            extension::action_url_addons('create', [], ['bbb-meta' => 'Test'], $bbactivity->id);
166
        $this->assertEmpty($additionalvar1);
167
        $this->assertCount(2, $additionalvar2);
168
        $this->assertEquals($additionalvar2['newfield'], 4);
169
        ['data' => $additionalvar1, 'metadata' => $additionalvar2] = extension::action_url_addons('delete');
170
        $this->assertEmpty($additionalvar1);
171
        $this->assertEmpty($additionalvar2);
172
    }
173
 
174
    /**
175
     * Test the action_url_addons with plugin enabled
176
     *
177
     * @return void
178
     * @covers \mod_bigbluebuttonbn\extension::action_url_addons
179
     */
11 efrain 180
    public function test_join_url_with_additional_field(): void {
1 efrain 181
        $this->initialise_mock_server();
182
        // Enable plugin.
183
        $this->enable_plugins(true);
184
        $course = $this->get_course();
185
        [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
186
        $bbactivity->newfield = 4;
187
        extension::update_instance($bbactivity);
188
        $instance = instance::get_from_instanceid($bbactivity->id);
189
        $meeting = new meeting($instance);
190
        $meetingjoinurl = $meeting->get_join_url();
191
        $this->assertStringContainsString('newfield=4', $meetingjoinurl);
192
    }
193
 
194
    /**
195
     * Test backup restore (with extension)
196
     *
197
     * @covers       \backup_bigbluebuttonbn_activity_task
198
     */
199
    public function test_backup_restore(): void {
200
        global $DB, $CFG, $USER;
201
        require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
202
        require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
203
        $this->resetAfterTest();
204
        $course = $this->get_course();
205
        [$cm, $cminfo, $bbactivity] = $this->create_instance($course);
206
        $bbactivity->newfield = 4;
207
        extension::update_instance($bbactivity);
208
 
209
        $this->setAdminUser();
210
 
211
        $CFG->backup_file_logger_level = backup::LOG_NONE;
212
 
213
        // Do backup with default settings.
214
        set_config('backup_general_users', 1, 'backup');
215
        $bc = new backup_controller(backup::TYPE_1COURSE, $course->id,
216
            backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_GENERAL,
217
            $USER->id);
218
        $bc->execute_plan();
219
        $results = $bc->get_results();
220
        $file = $results['backup_destination'];
221
        $fp = get_file_packer('application/vnd.moodle.backup');
222
        $filepath = $CFG->dataroot . '/temp/backup/test-restore-course';
223
        $file->extract_to_pathname($fp, $filepath);
224
        $bc->destroy();
225
 
226
        // Do restore to new course with default settings.
227
        $newcourseid = restore_dbops::create_new_course(
228
            $course->fullname, $course->shortname . '_2', $course->category);
229
        $rc = new restore_controller('test-restore-course', $newcourseid,
230
            backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id,
231
            backup::TARGET_NEW_COURSE);
232
        $rc->execute_precheck();
233
        $rc->execute_plan();
234
        $rc->destroy();
235
        $cms = get_fast_modinfo($newcourseid)->get_cms();
236
        $newmoduleid = null;
237
        foreach ($cms as $id => $cm) {
238
            if ($cm->modname == 'bigbluebuttonbn') {
239
                $newmoduleid = $cm->instance;
240
            }
241
        }
242
        // Check instance has been copied.
243
        $this->assertNotNull($newmoduleid);
244
 
245
        // Change the original instance value (this makes sure we are not looking at the same value in the
246
        // original and copy).
247
        $bbactivity->newfield = 5;
248
        extension::update_instance($bbactivity);
249
 
250
        // Now check the copied instance.
251
        $newfieldrecord = $DB->get_record('bbbext_simple', [
252
            'bigbluebuttonbnid' => $newmoduleid,
253
        ]);
254
        $this->assertNotNull($newfieldrecord);
255
        $this->assertEquals(4, $newfieldrecord->newfield);
256
        // And the original.
257
        $oldfieldrecord = $DB->get_record('bbbext_simple', [
258
            'bigbluebuttonbnid' => $bbactivity->id,
259
        ]);
260
        $this->assertNotNull($oldfieldrecord);
261
        $this->assertEquals(5, $oldfieldrecord->newfield);
262
    }
263
 
264
    /**
265
     * Test completion with and without addons.
266
     *
267
     * @param array $customcompletionrules
268
     * @param array $events
269
     * @param int $expectedstate
270
     * @return void
271
     * @dataProvider custom_completion_data_provider
272
     * @covers \mod_bigbluebuttonbn\local\extension\custom_completion_addons
273
     */
274
    public function test_additional_completion(array $customcompletionrules, array $events, int $expectedstate): void {
275
        // Enable plugin.
276
        $this->enable_plugins(true);
277
        $this->initialise_mock_server();
278
        list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance(
279
            $this->get_course(),
280
            array_merge([
281
                'completion' => '2',
282
            ], $customcompletionrules)
283
        );
284
 
285
        $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
286
 
287
        $user = $this->getDataGenerator()->create_user();
288
        $this->setUser($user);
289
 
290
        // Now create a couple of events.
291
        $instance = instance::get_from_instanceid($bbactivity->id);
292
        set_config('bigbluebuttonbn_meetingevents_enabled', true);
293
        $meeting = $plugingenerator->create_meeting([
294
            'instanceid' => $instance->get_instance_id(),
295
            'groupid' => $instance->get_group_id(),
296
            'participants' => json_encode([$user->id]),
297
        ]);
298
        foreach ($events as $edesc) {
299
            $plugingenerator->add_meeting_event($user, $instance, $edesc->name, $edesc->data ?? '');
300
        }
301
        $result = $plugingenerator->send_all_events($instance);
302
        $this->assertNotEmpty($result->data);
303
        $data = json_decode(json_encode($result->data));
304
        meeting::meeting_events($instance, $data);
305
        $completion = new custom_completion($bbactivitycm, $user->id);
306
        $result = $completion->get_overall_completion_state();
307
        $this->assertEquals($expectedstate, $result);
308
 
309
    }
310
 
311
    /**
312
     * Data generator
313
     *
314
     * @return array[]
315
     */
316
    public static function custom_completion_data_provider(): array {
317
        global $CFG;
318
        require_once($CFG->libdir . '/completionlib.php');
319
        return [
320
            'simple' => [
321
                'customcompletionrules' => [
322
                    'completionengagementtalks' => 1,
323
                    'completionextraisehandtwice' => 1,
324
                ],
325
                'events' => [
326
                    (object) ['name' => 'talks'],
327
                    (object) ['name' => 'raisehand'],
328
                    (object) ['name' => 'raisehand'],
329
                ],
330
                'expectedstate' => COMPLETION_COMPLETE,
331
            ],
332
            'not right events' => [
333
                'customcompletionrules' => [
334
                    'completionextraisehandtwice' => 1,
335
                ],
336
                'events' => [
337
                    (object) ['name' => 'chats'],
338
                ],
339
                'expectedstate' => COMPLETION_INCOMPLETE,
340
            ],
341
            'not enough events' => [
342
                'customcompletionrules' => [
343
                    'completionextraisehandtwice' => 1,
344
                ],
345
                'events' => [
346
                    (object) ['name' => 'raisehand'],
347
                ],
348
                'expectedstate' => COMPLETION_INCOMPLETE,
349
            ],
350
            'more events' => [
351
                'customcompletionrules' => [
352
                    'completionengagementtalks' => 1,
353
                ],
354
                'events' => [
355
                    (object) ['name' => 'talks'],
356
                    (object) ['name' => 'talks'],
357
                    (object) ['name' => 'talks'],
358
                ],
359
                'expectedstate' => COMPLETION_COMPLETE,
360
            ],
361
            'basics are still working' => [
362
                'customcompletionrules' => [
363
                    'completionengagementtalks' => 1,
364
                ],
365
                'events' => [
366
                    (object) ['name' => 'talks'],
367
                ],
368
                'expectedstate' => COMPLETION_COMPLETE,
369
            ],
370
        ];
371
    }
372
 
373
    /**
1441 ariadna 374
     * Test broker meeting_events with and without addons.
375
     * @return void
376
     * @covers \mod_bigbluebuttonbn\local\extension\broker_meeting_events_addons
377
     */
378
    public function test_broker_meeting_events_addons(): void {
379
        $this->resetAfterTest();
380
        global $DB;
381
        // Enable plugin.
382
        $this->enable_plugins(true);
383
        $this->initialise_mock_server();
384
        [$bbactivitycontext, $bbactivitycm, $bbactivity] = $this->create_instance(
385
            $this->get_course());
386
        $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_bigbluebuttonbn');
387
        $user = $this->getDataGenerator()->create_user();
388
        $this->setUser($user);
389
 
390
        // Now create a couple of events.
391
        $instance = instance::get_from_instanceid($bbactivity->id);
392
        set_config('bigbluebuttonbn_meetingevents_enabled', true);
393
        $meeting = $plugingenerator->create_meeting([
394
            'instanceid' => $instance->get_instance_id(),
395
            'groupid' => $instance->get_group_id(),
396
            'participants' => json_encode([$user->id]),
397
        ]);
398
 
399
        $events = [
400
            (object) ['name' => 'talks'],
401
            (object) ['name' => 'raisehand'],
402
            (object) ['name' => 'raisehand'],
403
        ];
404
        foreach ($events as $edesc) {
405
            $plugingenerator->add_meeting_event($user, $instance, $edesc->name, $edesc->data ?? '');
406
        }
407
        $result = $plugingenerator->send_all_events($instance);
408
        $this->assertNotEmpty($result->data);
409
        $data = json_encode($result->data);
410
        $reflection = new \ReflectionClass(broker::class);
411
        $method = $reflection->getMethod('process_extension_actions');
412
        $method->setAccessible(true);
413
        $method->invokeArgs(null, [$instance, $data]);
414
        $addondata = $DB->get_field('bbbext_simple', 'meetingevents', ['bigbluebuttonbnid' => $bbactivity->id]);
415
        $addondata = json_decode($addondata);
416
        // Check that the data is received.
417
        $this->assertEquals(json_encode($addondata), $data);
418
    }
419
 
420
 
421
    /**
1 efrain 422
     * Data provider for testing get_class_implementing
423
     *
424
     * @return array[]
425
     */
1441 ariadna 426
    public static function classes_implementing_class(): array {
1 efrain 427
        return [
428
            'mod_instance_helper with plugin disabled' => [
429
                'bbbenabled' => false,
430
                'apiclass' => mod_instance_helper::class,
1441 ariadna 431
                'extensionclasses' => [],
1 efrain 432
            ],
433
            'mod_instance_helper with plugin enabled' => [
434
                'bbbenabled' => true,
435
                'apiclass' => mod_instance_helper::class,
1441 ariadna 436
                'extensionclasses' => [
1 efrain 437
                    'bbbext_simple\\bigbluebuttonbn\\mod_instance_helper',
438
                ],
439
            ],
440
        ];
441
    }
442
 
443
    /**
1441 ariadna 444
     * Test the get_sorted_plugins_list
445
     * @param array $sortorders
446
     * @param array $expected
447
     * @return void
448
     * @dataProvider sorted_plugins_list_data_provider
449
     * @covers \mod_bigbluebuttonbn\extension::get_sorted_plugins_list
450
     */
451
    public function test_get_sorted_plugins_list(array $sortorders, array $expected): void {
452
        $this->resetAfterTest();
453
        // Enable plugin.
454
        $this->enable_plugins(true);
455
        // Create list of plugins we will then sort.
456
        $pluginlist = [
457
            'simpleone' => '/path/to/simpleone',
458
            'simpletwo' => '/path/to/simpletwo',
459
        ];
460
        // Set sortorder.
461
        foreach ($sortorders as $plugin => $sortorder) {
462
            set_config('sortorder', $sortorder, 'bbbext_' . $plugin);
463
        }
464
        $sortedlist = extension::get_sorted_plugins_list($pluginlist);
465
        $this->assertSame($expected, $sortedlist);
466
    }
467
 
468
    /**
469
     * Data provider for testing get_sorted_plugins_list
470
     *
471
     * @return array[]
472
     */
473
    public static function sorted_plugins_list_data_provider(): array {
474
        return [
475
            'no sortorder' => [
476
                [],
477
                ['simpleone', 'simpletwo'],
478
            ],
479
            'default sortorder' => [
480
                ['simpleone' => 0, 'simpletwo' => 1],
481
                ['simpleone', 'simpletwo'],
482
            ],
483
            'changed sortorder' => [
484
                ['simpleone' => 1, 'simpletwo' => 0],
485
                ['simpletwo', 'simpleone'],
486
            ],
487
        ];
488
    }
489
 
490
    /**
1 efrain 491
     * Enable plugins
492
     *
493
     * @param bool $bbbenabled
494
     * @return void
495
     */
496
    private function enable_plugins(bool $bbbenabled) {
497
        // First make sure that either BBB is enabled or not.
498
        \core\plugininfo\mod::enable_plugin('bigbluebuttonbn', $bbbenabled ? 1 : 0);
499
        $plugin = extension::BBB_EXTENSION_PLUGIN_NAME . '_simple';
500
        if ($bbbenabled) {
501
            unset_config('disabled', $plugin);
502
        } else {
503
            set_config('disabled', 'disabled', $plugin);
504
        }
505
    }
506
}