Proyectos de Subversion Moodle

Rev

Rev 1 | | 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
 
17
namespace core_adminpresets;
18
 
19
use moodle_exception;
20
use stdClass;
21
 
22
/**
23
 * Tests for the manager class.
24
 *
25
 * @package    core_adminpresets
26
 * @category   test
27
 * @copyright  2021 Sara Arjona (sara@moodle.com)
28
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29
 * @coversDefaultClass \core_adminpresets\manager
30
 */
1441 ariadna 31
final class manager_test extends \advanced_testcase {
1 efrain 32
    /**
33
     * Include required libraries.
34
     */
35
    public static function setUpBeforeClass(): void {
36
        global $CFG;
37
        require_once($CFG->libdir.'/adminlib.php');
1441 ariadna 38
        parent::setUpBeforeClass();
1 efrain 39
    }
40
 
41
    /**
42
     * Test the behaviour of protected get_site_settings method.
43
     *
44
     * @covers ::get_site_settings
45
     * @covers ::get_settings
46
     */
47
    public function test_manager_get_site_settings(): void {
48
        global $DB;
49
 
50
        $this->resetAfterTest();
51
 
52
        // Login as admin, to access all the settings.
53
        $this->setAdminUser();
54
 
55
        $manager = new manager();
56
        $result = $manager->get_site_settings();
57
 
58
        // Check fullname is set into the none category.
59
        $this->assertInstanceOf(
60
                '\core_adminpresets\local\setting\adminpresets_admin_setting_sitesettext',
61
                $result['none']['fullname']
62
        );
63
        $this->assertEquals('PHPUnit test site', $result['none']['fullname']->get_value());
64
 
65
        // Check some of the config setting is present (they should be stored in the "none" category).
66
        $this->assertInstanceOf(
67
                '\core_adminpresets\local\setting\adminpresets_admin_setting_configcheckbox',
68
                $result['none']['enablecompletion']
69
        );
70
        $this->assertEquals(1, $result['none']['enablecompletion']->get_value());
71
 
72
        // Check some of the plugin config settings is present.
73
        $this->assertInstanceOf(
74
                '\core_adminpresets\local\setting\adminpresets_admin_setting_configtext',
75
                $result['folder']['maxsizetodownload']
76
        );
77
        $this->assertEquals(0, $result['folder']['maxsizetodownload']->get_value());
78
 
79
        // Set some of these values.
80
        $sitecourse = new stdClass();
81
        $sitecourse->id = 1;
82
        $sitecourse->fullname = 'New site fullname';
83
        $DB->update_record('course', $sitecourse);
84
 
85
        set_config('enablecompletion', 0);
86
        set_config('maxsizetodownload', 101, 'folder');
87
 
88
        // Check the new values are returned properly.
89
        $result = $manager->get_site_settings();
90
        // Site fullname.
91
        $this->assertInstanceOf(
92
                '\core_adminpresets\local\setting\adminpresets_admin_setting_sitesettext',
93
                $result['none']['fullname']
94
        );
95
        $this->assertEquals($sitecourse->fullname, $result['none']['fullname']->get_value());
96
        // Config setting.
97
        $this->assertInstanceOf(
98
                '\core_adminpresets\local\setting\adminpresets_admin_setting_configcheckbox',
99
                $result['none']['enablecompletion']
100
        );
101
        $this->assertEquals(0, $result['none']['enablecompletion']->get_value());
102
        // Plugin config settting.
103
        $this->assertInstanceOf(
104
                '\core_adminpresets\local\setting\adminpresets_admin_setting_configtext',
105
                $result['folder']['maxsizetodownload']
106
        );
107
        $this->assertEquals(101, $result['folder']['maxsizetodownload']->get_value());
108
    }
109
 
110
    /**
111
     * Test the behaviour of protected get_setting method.
112
     *
113
     * @covers ::get_setting
114
     * @covers ::get_settings_class
115
     */
116
    public function test_manager_get_setting(): void {
117
        $this->resetAfterTest();
118
 
119
        // Login as admin, to access all the settings.
120
        $this->setAdminUser();
121
 
122
        $adminroot = admin_get_root();
123
 
124
        // Check the adminpresets_xxxxx class is created properly when it exists.
125
        $settingpage = $adminroot->locate('optionalsubsystems');
126
        $settingdata = $settingpage->settings->enablebadges;
127
        $manager = new manager();
128
        $result = $manager->get_setting($settingdata, '');
129
        $this->assertInstanceOf('\core_adminpresets\local\setting\adminpresets_admin_setting_configcheckbox', $result);
130
        $this->assertNotEquals('core_adminpresets\local\setting\adminpresets_setting', get_class($result));
131
 
132
        // Check the mapped class is returned when no specific class exists and it exists in the mappings array.
133
        $settingpage = $adminroot->locate('h5psettings');
134
        $settingdata = $settingpage->settings->h5plibraryhandler;;
135
        $result = $manager->get_setting($settingdata, '');
136
        $this->assertInstanceOf('\core_adminpresets\local\setting\adminpresets_admin_setting_configselect', $result);
137
        $this->assertNotEquals(
138
                'core_adminpresets\local\setting\adminpresets_admin_settings_h5plib_handler_select',
139
                get_class($result)
140
        );
141
 
142
        // Check the mapped class is returned when no specific class exists and it exists in the mappings array.
143
        $settingpage = $adminroot->locate('modsettingquiz');
144
        $settingdata = $settingpage->settings->quizbrowsersecurity;;
145
        $result = $manager->get_setting($settingdata, '');
146
        $this->assertInstanceOf(\mod_quiz\adminpresets\adminpresets_browser_security_setting::class, $result);
147
        $this->assertNotEquals(\core_adminpresets\local\setting\adminpresets_setting::class, get_class($result));
148
 
149
        // Check the adminpresets_setting class is returned when no specific class exists.
150
        $settingpage = $adminroot->locate('managecustomfields');
151
        $settingdata = $settingpage->settings->customfieldsui;;
152
        $result = $manager->get_setting($settingdata, '');
153
        $this->assertInstanceOf('\core_adminpresets\local\setting\adminpresets_setting', $result);
154
        $this->assertEquals('core_adminpresets\local\setting\adminpresets_setting', get_class($result));
155
    }
156
 
157
    /**
158
     * Test the behaviour of apply_preset() method when the given presetid doesn't exist.
159
     *
160
     * @covers ::apply_preset
161
     */
162
    public function test_apply_preset_unexisting_preset(): void {
163
        $this->resetAfterTest();
164
        $this->setAdminUser();
165
 
166
        // Create some presets.
167
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
168
        $presetid = $generator->create_preset();
169
 
170
        // Unexisting preset identifier.
171
        $unexistingid = $presetid * 2;
172
 
173
        $manager = new manager();
174
        $this->expectException(\moodle_exception::class);
175
        $manager->apply_preset($unexistingid);
176
    }
177
 
178
    /**
179
     * Test the behaviour of apply_preset() method.
180
     *
181
     * @covers ::apply_preset
182
     */
183
    public function test_apply_preset(): void {
184
        global $DB;
185
 
186
        $this->resetAfterTest();
187
        $this->setAdminUser();
188
 
189
        // Create a preset.
190
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
191
        $presetid = $generator->create_preset();
192
 
193
        $currentpresets = $DB->count_records('adminpresets');
194
        $currentitems = $DB->count_records('adminpresets_it');
195
        $currentadvitems = $DB->count_records('adminpresets_it_a');
196
        $currentplugins = $DB->count_records('adminpresets_plug');
197
        $currentapppresets = $DB->count_records('adminpresets_app');
198
        $currentappitems = $DB->count_records('adminpresets_app_it');
199
        $currentappadvitems = $DB->count_records('adminpresets_app_it_a');
200
        $currentappplugins = $DB->count_records('adminpresets_app_plug');
201
 
202
        // Set the config values (to confirm they change after applying the preset).
203
        set_config('enablebadges', 1);
204
        set_config('allowemojipicker', 1);
205
        set_config('mediawidth', '640', 'mod_lesson');
206
        set_config('maxanswers', '5', 'mod_lesson');
207
        set_config('maxanswers_adv', '1', 'mod_lesson');
208
        set_config('enablecompletion', 1);
209
        set_config('usecomments', 0);
210
 
211
        // Call the apply_preset method.
212
        $manager = new manager();
213
        $manager->apply_preset($presetid);
214
 
215
        // Check the preset applied has been added to database.
216
        $this->assertCount($currentapppresets + 1, $DB->get_records('adminpresets_app'));
217
        // Applied items: enablebadges@none, mediawitdh@mod_lesson and maxanswers@@mod_lesson.
218
        $this->assertCount($currentappitems + 3, $DB->get_records('adminpresets_app_it'));
219
        // Applied advanced items: maxanswers_adv@mod_lesson.
220
        $this->assertCount($currentappadvitems + 1, $DB->get_records('adminpresets_app_it_a'));
221
        // Applied plugins: enrol_guest and mod_glossary.
222
        $this->assertCount($currentappplugins + 2, $DB->get_records('adminpresets_app_plug'));
223
        // Check no new preset has been created.
224
        $this->assertCount($currentpresets, $DB->get_records('adminpresets'));
225
        $this->assertCount($currentitems, $DB->get_records('adminpresets_it'));
226
        $this->assertCount($currentadvitems, $DB->get_records('adminpresets_it_a'));
227
        $this->assertCount($currentplugins, $DB->get_records('adminpresets_plug'));
228
 
229
        // Check the setting values have changed accordingly with the ones defined in the preset.
230
        $this->assertEquals(0, get_config('core', 'enablebadges'));
231
        $this->assertEquals(900, get_config('mod_lesson', 'mediawidth'));
232
        $this->assertEquals(2, get_config('mod_lesson', 'maxanswers'));
233
        $this->assertEquals(0, get_config('mod_lesson', 'maxanswers_adv'));
234
 
235
        // These settings will never change.
236
        $this->assertEquals(1, get_config('core', 'allowemojipicker'));
237
        $this->assertEquals(1, get_config('core', 'enablecompletion'));
238
        $this->assertEquals(0, get_config('core', 'usecomments'));
239
 
240
        // Check the plugins visibility have changed accordingly with the ones defined in the preset.
241
        $enabledplugins = \core\plugininfo\enrol::get_enabled_plugins();
242
        $this->assertArrayNotHasKey('guest', $enabledplugins);
243
        $this->assertArrayHasKey('manual', $enabledplugins);
244
        $enabledplugins = \core\plugininfo\mod::get_enabled_plugins();
245
        $this->assertArrayNotHasKey('glossary', $enabledplugins);
246
        $this->assertArrayHasKey('assign', $enabledplugins);
247
        $enabledplugins = \core\plugininfo\qtype::get_enabled_plugins();
248
        $this->assertArrayHasKey('truefalse', $enabledplugins);
249
 
250
        // Check the presetid has been also stored in the lastpresetapplied config setting.
251
        $this->assertEquals($presetid, get_config('adminpresets', 'lastpresetapplied'));
252
 
253
        // Call apply_preset as a simulation, so it shouldn't be applied and lastpresetapplied should still be $presetid.
254
        $presetid2 = $generator->create_preset();
255
        $manager->apply_preset($presetid2, true);
256
        $this->assertEquals($presetid, get_config('adminpresets', 'lastpresetapplied'));
257
    }
258
 
259
 
260
    /**
261
     * Test the behaviour of export_preset() method.
262
     *
263
     * @covers ::export_preset
264
     * @dataProvider export_preset_provider
265
     *
266
     * @param bool $includesensible Whether the sensible settings should be exported too or not.
267
     * @param string $presetname Preset name.
268
     */
269
    public function test_export_preset(bool $includesensible = false, string $presetname = 'Export 1'): void {
270
        global $DB;
271
 
272
        $this->resetAfterTest();
273
        $this->setAdminUser();
274
 
275
        // Get current presets and items.
276
        $currentpresets = $DB->count_records('adminpresets');
277
        $currentadvitems = $DB->count_records('adminpresets_it_a');
278
 
279
        // Initialise some settings (to compare their values have been exported as expected).
280
        set_config('recaptchapublickey', 'abcde');
281
        set_config('enablebadges', '0');
282
        set_config('mediawidth', '900', 'mod_lesson');
283
        set_config('maxanswers', '2', 'mod_lesson');
284
        set_config('maxanswers_adv', '0', 'mod_lesson');
285
        set_config('defaultfeedback', '0', 'mod_lesson');
286
        set_config('defaultfeedback_adv', '1', 'mod_lesson');
287
 
288
        // Prepare the data to export preset.
289
        $data = [
290
            'name' => $presetname,
291
            'comments' => ['text' => 'This is a presets for testing export'],
292
            'author' => 'Super-Girl',
293
            'includesensiblesettings' => $includesensible,
294
        ];
295
 
296
        // Call the method to be tested.
297
        $manager = new manager();
298
        list($presetid, $settingsfound, $pluginsfound) = $manager->export_preset((object) $data);
299
 
300
        // Check the preset record has been created.
301
        $presets = $DB->get_records('adminpresets');
302
        $this->assertCount($currentpresets + 1, $presets);
303
        $this->assertArrayHasKey($presetid, $presets);
304
        $preset = $presets[$presetid];
305
        $this->assertEquals($presetname, $preset->name);
306
        $this->assertEquals(manager::NONCORE_PRESET, $preset->iscore);
307
 
308
        // Check the preset includes settings and plugins.
309
        $this->assertTrue($settingsfound);
310
        $this->assertTrue($pluginsfound);
311
 
312
        // Check the items, advanced attributes and plugins have been created.
313
        $this->assertGreaterThan(0, $DB->count_records('adminpresets_it', ['adminpresetid' => $presetid]));
314
        $this->assertGreaterThan($currentadvitems, $DB->count_records('adminpresets_it_a'));
315
        $this->assertGreaterThan(0, $DB->count_records('adminpresets_plug', ['adminpresetid' => $presetid]));
316
 
317
        // Check settings have been created with the expected values.
318
        $params = ['adminpresetid' => $presetid, 'plugin' => 'none', 'name' => 'enablebadges'];
319
        $setting = $DB->get_record('adminpresets_it', $params);
320
        $this->assertEquals('0', $setting->value);
321
 
322
        $params = ['adminpresetid' => $presetid, 'plugin' => 'mod_lesson', 'name' => 'mediawidth'];
323
        $setting = $DB->get_record('adminpresets_it', $params);
324
        $this->assertEquals('900', $setting->value);
325
 
326
        $params = ['adminpresetid' => $presetid, 'plugin' => 'mod_lesson', 'name' => 'maxanswers'];
327
        $setting = $DB->get_record('adminpresets_it', $params);
328
        $this->assertEquals('2', $setting->value);
329
        $params = ['itemid' => $setting->id, 'name' => 'maxanswers_adv'];
330
        $setting = $DB->get_record('adminpresets_it_a', $params);
331
        $this->assertEquals('0', $setting->value);
332
 
333
        $params = ['adminpresetid' => $presetid, 'plugin' => 'mod_lesson', 'name' => 'defaultfeedback'];
334
        $setting = $DB->get_record('adminpresets_it', $params);
335
        $this->assertEquals('0', $setting->value);
336
        $params = ['itemid' => $setting->id, 'name' => 'defaultfeedback_adv'];
337
        $setting = $DB->get_record('adminpresets_it_a', $params);
338
        $this->assertEquals('1', $setting->value);
339
 
340
        // Check plugins have been created with the expected values.
341
        $manager = \core_plugin_manager::instance();
342
        $plugintype = 'enrol';
343
        $plugins = $manager->get_present_plugins($plugintype);
344
        $enabledplugins = $manager->get_enabled_plugins($plugintype);
345
        foreach ($plugins as $pluginname => $unused) {
346
            $params = ['adminpresetid' => $presetid, 'plugin' => $plugintype, 'name' => $pluginname];
347
            $plugin = $DB->get_record('adminpresets_plug', $params);
348
            $enabled = (!empty($enabledplugins) && array_key_exists($pluginname, $enabledplugins));
349
            $this->assertEquals($enabled, (bool) $plugin->enabled);
350
        }
351
 
352
        // Check whether sensible settings have been exported or not.
353
        $params = ['adminpresetid' => $presetid, 'plugin' => 'none', 'name' => 'recaptchapublickey'];
354
        $recaptchasetting = $DB->get_record('adminpresets_it', $params);
355
        $params = ['adminpresetid' => $presetid, 'plugin' => 'none', 'name' => 'cronremotepassword'];
356
        $cronsetting = $DB->get_record('adminpresets_it', $params);
357
        if ($includesensible) {
358
            $this->assertEquals('abcde', $recaptchasetting->value);
359
            $this->assertNotFalse($cronsetting);
360
        } else {
361
            $this->assertFalse($recaptchasetting);
362
            $this->assertFalse($cronsetting);
363
        }
364
    }
365
 
366
    /**
367
     * Data provider for test_export_preset().
368
     *
369
     * @return array
370
     */
1441 ariadna 371
    public static function export_preset_provider(): array {
1 efrain 372
        return [
373
            'Export settings and plugins, excluding sensible' => [
374
                'includesensible' => false,
375
            ],
376
            'Export settings and plugins, including sensible' => [
377
                'includesensible' => true,
378
            ],
379
            'Export settings and plugins, with Starter name (it should not be marked as core)' => [
380
                'includesensible' => false,
381
                'presetname' => 'Starter',
382
            ],
383
            'Export settings and plugins, with Full name (it should not be marked as core)' => [
384
                'includesensible' => false,
385
                'presetname' => 'Full',
386
            ],
387
        ];
388
    }
389
 
390
    /**
391
     * Test the behaviour of download_preset() method, when the given presetid doesn't exist.
392
     *
393
     * @covers ::download_preset
394
     */
395
    public function test_download_unexisting_preset(): void {
396
        $this->resetAfterTest();
397
        $this->setAdminUser();
398
 
399
        // Create some presets.
400
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
401
        $presetid = $generator->create_preset();
402
 
403
        // Unexisting preset identifier.
404
        $unexistingid = $presetid * 2;
405
 
406
        $manager = new manager();
407
        $this->expectException(\moodle_exception::class);
408
        $manager->download_preset($unexistingid);
409
    }
410
 
411
 
412
    /**
413
     * Test the behaviour of import_preset() method.
414
     *
415
     * @dataProvider import_preset_provider
416
     * @covers ::import_preset
417
     *
418
     * @param string $filecontents File content to import.
419
     * @param bool $expectedpreset Whether the preset should be created or not.
420
     * @param bool $expectedsettings Whether settings will be created or not.
421
     * @param bool $expectedplugins Whether plugins will be created or not.
422
     * @param bool $expecteddebugging Whether debugging message will be thrown or not.
423
     * @param string|null $expectedexception Expected exception class (if that's the case).
424
     * @param string|null $expectedpresetname Expected preset name.
425
     */
426
    public function test_import_preset(string $filecontents, bool $expectedpreset, bool $expectedsettings = false,
1441 ariadna 427
            bool $expectedplugins = false, bool $expecteddebugging = false, ?string $expectedexception = null,
1 efrain 428
            string $expectedpresetname = 'Imported preset'): void {
429
        global $DB;
430
 
431
        $this->resetAfterTest();
432
        $this->setAdminUser();
433
 
434
        $currentpresets = $DB->count_records('adminpresets');
435
        $currentitems = $DB->count_records('adminpresets_it');
436
        $currentadvitems = $DB->count_records('adminpresets_it_a');
437
 
438
        // Call the method to be tested.
439
        $manager = new manager();
440
        try {
1441 ariadna 441
            $invokable = self::get_invokable();
442
            set_error_handler($invokable, E_WARNING);
1 efrain 443
            list($xml, $preset, $settingsfound, $pluginsfound) = $manager->import_preset($filecontents);
1441 ariadna 444
            restore_error_handler();
1 efrain 445
        } catch (\exception $e) {
446
            if ($expectedexception) {
447
                $this->assertInstanceOf($expectedexception, $e);
448
            }
449
        } finally {
450
            if ($expecteddebugging) {
451
                $this->assertDebuggingCalled();
452
            }
453
 
454
            if ($expectedpreset) {
455
                // Check the preset record has been created.
456
                $presets = $DB->get_records('adminpresets');
457
                $this->assertCount($currentpresets + 1, $presets);
458
                $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
459
                $this->assertArrayHasKey($preset->id, $presets);
460
                $preset = $presets[$preset->id];
461
                $this->assertEquals($expectedpresetname, $preset->name);
462
                $this->assertEquals('http://demo.moodle', $preset->site);
463
                $this->assertEquals('Ada Lovelace', $preset->author);
464
                $this->assertEquals(manager::NONCORE_PRESET, $preset->iscore);
465
 
466
                if ($expectedsettings) {
467
                    // Check the items have been created.
468
                    $items = $DB->get_records('adminpresets_it', ['adminpresetid' => $preset->id]);
469
                    $this->assertCount(4, $items);
470
                    $presetitems = [
471
                        'none' => [
472
                            'enablebadges' => 0,
473
                            'enableportfolios' => 1,
474
                            'allowemojipicker' => 1,
475
                        ],
476
                        'mod_lesson' => [
477
                            'mediawidth' => 900,
478
                            'maxanswers' => 2,
479
                        ],
480
                    ];
481
                    foreach ($items as $item) {
482
                        $this->assertArrayHasKey($item->name, $presetitems[$item->plugin]);
483
                        $this->assertEquals($presetitems[$item->plugin][$item->name], $item->value);
484
                    }
485
 
486
                    // Check the advanced attributes have been created.
487
                    $advitems = $DB->get_records('adminpresets_it_a');
488
                    $this->assertCount($currentadvitems + 1, $advitems);
489
                    $advitemfound = false;
490
                    foreach ($advitems as $advitem) {
491
                        if ($advitem->name == 'maxanswers_adv') {
492
                            $this->assertEmpty($advitem->value);
493
                            $advitemfound = true;
494
                        }
495
                    }
496
                    $this->assertTrue($advitemfound);
497
                }
498
 
499
                if ($expectedplugins) {
500
                    // Check the plugins have been created.
501
                    $plugins = $DB->get_records('adminpresets_plug', ['adminpresetid' => $preset->id]);
502
                    $this->assertCount(6, $plugins);
503
                    $presetplugins = [
504
                        'atto' => [
505
                            'html' => 1,
506
                        ],
507
                        'block' => [
508
                            'html' => 0,
509
                            'activity_modules' => 1,
510
                        ],
511
                        'mod' => [
1441 ariadna 512
                            'page' => 0,
1 efrain 513
                            'data' => 0,
514
                            'lesson' => 1,
515
                        ],
516
                    ];
517
                    foreach ($plugins as $plugin) {
518
                        $this->assertArrayHasKey($plugin->name, $presetplugins[$plugin->plugin]);
519
                        $this->assertEquals($presetplugins[$plugin->plugin][$plugin->name], $plugin->enabled);
520
                    }
521
 
522
                }
523
            } else {
524
                // Check the preset nor the items are not created.
525
                $this->assertCount($currentpresets, $DB->get_records('adminpresets'));
526
                $this->assertCount($currentitems, $DB->get_records('adminpresets_it'));
527
                $this->assertCount($currentadvitems, $DB->get_records('adminpresets_it_a'));
528
            }
529
        }
530
    }
531
 
532
    /**
533
     * Data provider for test_import_preset().
534
     *
535
     * @return array
536
     */
1441 ariadna 537
    public static function import_preset_provider(): array {
1 efrain 538
        return [
539
            'Import settings from an empty file' => [
540
                'filecontents' => '',
541
                'expectedpreset' => false,
542
            ],
543
            'Import settings and plugins from a valid XML file' => [
1441 ariadna 544
                'filecontents' => file_get_contents(
545
                    filename: self::get_fixture_path(__NAMESPACE__, 'import_settings_plugins.xml')
546
                ),
1 efrain 547
                'expectedpreset' => true,
548
                'expectedsettings' => true,
549
                'expectedplugins' => true,
550
            ],
551
            'Import only settings from a valid XML file' => [
1441 ariadna 552
                'filecontents' => file_get_contents(
553
                    filename: self::get_fixture_path(__NAMESPACE__, 'import_settings.xml')
554
                ),
1 efrain 555
                'expectedpreset' => true,
556
                'expectedsettings' => true,
557
                'expectedplugins' => false,
558
            ],
559
            'Import settings and plugins from a valid XML file with Starter name, which will be marked as non-core' => [
1441 ariadna 560
                'filecontents' => file_get_contents(
561
                    filename: self::get_fixture_path(__NAMESPACE__, 'import_starter_name.xml')
562
                ),
1 efrain 563
                'expectedpreset' => true,
564
                'expectedsettings' => true,
565
                'expectedplugins' => true,
566
                'expecteddebugging' => false,
567
                'expectedexception' => null,
568
                'expectedpresetname' => 'Starter',
569
            ],
570
            'Import settings from an invalid XML file' => [
1441 ariadna 571
                'filecontents' => file_get_contents(
572
                    filename: self::get_fixture_path(__NAMESPACE__, 'invalid_xml_file.xml')
573
                ),
1 efrain 574
                'expectedpreset' => false,
575
                'expectedsettings' => false,
576
                'expectedplugins' => false,
577
                'expecteddebugging' => false,
578
                'expectedexception' => \Exception::class,
579
            ],
580
            'Import unexisting settings category' => [
1441 ariadna 581
                'filecontents' => file_get_contents(
582
                    filename: self::get_fixture_path(__NAMESPACE__, 'unexisting_category.xml')
583
                ),
1 efrain 584
                'expectedpreset' => false,
585
                'expectedsettings' => false,
586
                'expectedplugins' => false,
587
            ],
588
            'Import unexisting setting' => [
1441 ariadna 589
                'filecontents' => file_get_contents(
590
                    filename: self::get_fixture_path(__NAMESPACE__, 'unexisting_setting.xml')
591
                ),
1 efrain 592
                'expectedpreset' => false,
593
                'expectedsettings' => false,
594
                'expectedplugins' => false,
595
                'expecteddebugging' => true,
596
            ],
597
            'Import valid settings with one unexisting setting too' => [
1441 ariadna 598
                'filecontents' => file_get_contents(
599
                    filename: self::get_fixture_path(__NAMESPACE__, 'import_settings_with_unexisting_setting.xml'),
600
                ),
1 efrain 601
                'expectedpreset' => true,
602
                'expectedsettings' => false,
603
                'expectedplugins' => false,
604
                'expecteddebugging' => true,
605
            ],
606
        ];
607
    }
608
 
609
    /**
610
     * Test the behaviour of delete_preset() method when the preset id doesn't exist.
611
     *
612
     * @covers ::delete_preset
613
     */
614
    public function test_delete_preset_unexisting_preset(): void {
615
 
616
        $this->resetAfterTest();
617
        $this->setAdminUser();
618
 
619
        // Create some presets.
620
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
621
        $presetid = $generator->create_preset(['name' => 'Preset 1']);
622
 
623
        // Unexisting preset identifier.
624
        $unexistingid = $presetid * 2;
625
 
626
        $manager = new manager();
627
 
628
        $this->expectException(moodle_exception::class);
629
        $this->expectExceptionMessage('Error deleting from database');
630
        $manager->delete_preset($unexistingid);
631
    }
632
 
633
    /**
634
     * Test trying to delete the core/pre-defined presets
635
     *
636
     * @covers ::delete_preset
637
     */
638
    public function test_delete_preset_core(): void {
639
        global $DB;
640
 
641
        $this->resetAfterTest();
642
 
643
        $starterpreset = $DB->get_record('adminpresets', ['iscore' => manager::STARTER_PRESET]);
644
 
645
        $this->expectException(moodle_exception::class);
646
        $this->expectExceptionMessage('Error deleting from database');
647
        (new manager())->delete_preset($starterpreset->id);
648
    }
649
 
650
    /**
651
     * Test the behaviour of delete_preset() method.
652
     *
653
     * @covers ::delete_preset
654
     */
655
    public function test_delete_preset(): void {
656
        global $DB;
657
 
658
        $this->resetAfterTest();
659
        $this->setAdminUser();
660
 
661
        // Create some presets.
662
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
663
        $presetid1 = $generator->create_preset(['name' => 'Preset 1', 'applypreset' => true]);
664
        $presetid2 = $generator->create_preset(['name' => 'Preset 2']);
665
 
666
        $currentpresets = $DB->count_records('adminpresets');
667
        $currentitems = $DB->count_records('adminpresets_it');
668
        $currentadvitems = $DB->count_records('adminpresets_it_a');
669
        $currentplugins = $DB->count_records('adminpresets_plug');
670
 
671
        // Only preset1 has been applied.
672
        $this->assertCount(1, $DB->get_records('adminpresets_app'));
673
        // Only the preset1 settings that have changed: enablebadges, mediawidth and maxanswers.
674
        $this->assertCount(3, $DB->get_records('adminpresets_app_it'));
675
        // Only the preset1 advanced settings that have changed: maxanswers_adv.
676
        $this->assertCount(1, $DB->get_records('adminpresets_app_it_a'));
677
        // Only the preset1 plugins that have changed: enrol_guest and mod_glossary.
678
        $this->assertCount(2, $DB->get_records('adminpresets_app_plug'));
679
 
680
        // Call the method to be tested.
681
        $manager = new manager();
682
        $manager->delete_preset($presetid1);
683
 
684
        // Check the preset data has been removed.
685
        $presets = $DB->get_records('adminpresets');
686
        $this->assertCount($currentpresets - 1, $presets);
687
        $preset = reset($presets);
688
        $this->assertArrayHasKey($presetid2, $presets);
689
        // Check preset items.
690
        $this->assertCount($currentitems - 4, $DB->get_records('adminpresets_it'));
691
        $this->assertCount(0, $DB->get_records('adminpresets_it', ['adminpresetid' => $presetid1]));
692
        // Check preset advanced items.
693
        $this->assertCount($currentadvitems - 1, $DB->get_records('adminpresets_it_a'));
694
        // Check preset plugins.
695
        $this->assertCount($currentplugins - 3, $DB->get_records('adminpresets_plug'));
696
        $this->assertCount(0, $DB->get_records('adminpresets_plug', ['adminpresetid' => $presetid1]));
697
        // Check preset applied tables are empty now.
698
        $this->assertCount(0, $DB->get_records('adminpresets_app'));
699
        $this->assertCount(0, $DB->get_records('adminpresets_app_it'));
700
        $this->assertCount(0, $DB->get_records('adminpresets_app_it_a'));
701
        $this->assertCount(0, $DB->get_records('adminpresets_app_plug'));
702
    }
703
 
704
    /**
705
     * Test the behaviour of revert_preset() method when the preset applied id doesn't exist.
706
     *
707
     * @covers ::revert_preset
708
     */
709
    public function test_revert_preset_unexisting_presetapp(): void {
710
        global $DB;
711
 
712
        $this->resetAfterTest();
713
        $this->setAdminUser();
714
 
715
        // Create a preset and apply it.
716
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
717
        $presetid = $generator->create_preset(['applypreset' => true]);
718
        $presetappid = $DB->get_field('adminpresets_app', 'id', ['adminpresetid' => $presetid]);
719
 
720
        // Unexisting applied preset identifier.
721
        $unexistingid = $presetappid * 2;
722
 
723
        $manager = new manager();
724
        $this->expectException(\moodle_exception::class);
725
        $manager->revert_preset($unexistingid);
726
    }
727
 
728
    /**
729
     * Test the behaviour of revert_preset() method.
730
     *
731
     * @covers ::revert_preset
732
     */
733
    public function test_revert_preset(): void {
734
        global $DB;
735
 
736
        $this->resetAfterTest();
737
        $this->setAdminUser();
738
 
739
        // Set the config values (to confirm they change after applying the preset).
740
        set_config('enablebadges', 1);
741
        set_config('allowemojipicker', 1);
742
        set_config('mediawidth', '640', 'mod_lesson');
743
        set_config('maxanswers', '5', 'mod_lesson');
744
        set_config('maxanswers_adv', '1', 'mod_lesson');
745
        set_config('enablecompletion', 1);
746
        set_config('usecomments', 0);
747
 
748
        // Create a preset and apply it.
749
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
750
        $presetid = $generator->create_preset(['applypreset' => true]);
751
        $presetappid = $DB->get_field('adminpresets_app', 'id', ['adminpresetid' => $presetid]);
752
 
753
        $currentpresets = $DB->count_records('adminpresets');
754
        $currentitems = $DB->count_records('adminpresets_it');
755
        $currentadvitems = $DB->count_records('adminpresets_it_a');
756
        $currentplugins = $DB->count_records('adminpresets_plug');
757
        $this->assertCount(1, $DB->get_records('adminpresets_app'));
758
        $this->assertCount(3, $DB->get_records('adminpresets_app_it'));
759
        $this->assertCount(1, $DB->get_records('adminpresets_app_it_a'));
760
        $this->assertCount(2, $DB->get_records('adminpresets_app_plug'));
761
 
762
        // Check the setttings have changed accordingly after applying the preset.
763
        $this->assertEquals(0, get_config('core', 'enablebadges'));
764
        $this->assertEquals(900, get_config('mod_lesson', 'mediawidth'));
765
        $this->assertEquals(2, get_config('mod_lesson', 'maxanswers'));
766
        $this->assertEquals(1, get_config('core', 'allowemojipicker'));
767
        $this->assertEquals(1, get_config('core', 'enablecompletion'));
768
        $this->assertEquals(0, get_config('core', 'usecomments'));
769
 
770
        // Check the plugins visibility have changed accordingly with the ones defined in the preset.
771
        $enabledplugins = \core\plugininfo\enrol::get_enabled_plugins();
772
        $this->assertArrayNotHasKey('guest', $enabledplugins);
773
        $enabledplugins = \core\plugininfo\mod::get_enabled_plugins();
774
        $this->assertArrayNotHasKey('glossary', $enabledplugins);
775
        $enabledplugins = \core\plugininfo\qtype::get_enabled_plugins();
776
        $this->assertArrayHasKey('truefalse', $enabledplugins);
777
 
778
        // Call the method to be tested.
779
        $manager = new manager();
780
        list($presetapp, $rollback, $failures) = $manager->revert_preset($presetappid);
781
 
782
        // Check the preset applied has been reverted (so the records in _appXX tables have been removed).
783
        $this->assertNotEmpty($presetapp);
784
        $this->assertNotEmpty($rollback);
785
        $this->assertEmpty($failures);
786
        $this->assertCount(0, $DB->get_records('adminpresets_app'));
787
        $this->assertCount(0, $DB->get_records('adminpresets_app_it'));
788
        $this->assertCount(0, $DB->get_records('adminpresets_app_it_a'));
789
        $this->assertCount(0, $DB->get_records('adminpresets_app_plug'));
790
        // Check the preset data hasn't changed.
791
        $this->assertCount($currentpresets, $DB->get_records('adminpresets'));
792
        $this->assertCount($currentitems, $DB->get_records('adminpresets_it'));
793
        $this->assertCount($currentadvitems, $DB->get_records('adminpresets_it_a'));
794
        $this->assertCount($currentplugins, $DB->get_records('adminpresets_plug'));
795
 
796
        // Check the setting values have been reverted accordingly.
797
        $this->assertEquals(1, get_config('core', 'enablebadges'));
798
        $this->assertEquals(640, get_config('mod_lesson', 'mediawidth'));
799
        $this->assertEquals(5, get_config('mod_lesson', 'maxanswers'));
800
        $this->assertEquals(1, get_config('mod_lesson', 'maxanswers_adv'));
801
        // These settings won't change, regardless if they are posted to the form.
802
        $this->assertEquals(1, get_config('core', 'allowemojipicker'));
803
        $this->assertEquals(1, get_config('core', 'enablecompletion'));
804
        $this->assertEquals(0, get_config('core', 'usecomments'));
805
 
806
        // Check the plugins visibility have been reverted accordingly.
807
        $enabledplugins = \core\plugininfo\enrol::get_enabled_plugins();
808
        $this->assertArrayHasKey('guest', $enabledplugins);
809
        $enabledplugins = \core\plugininfo\mod::get_enabled_plugins();
810
        $this->assertArrayHasKey('glossary', $enabledplugins);
811
        // This plugin won't change (because it had the same value than before the preset was applied).
812
        $enabledplugins = \core\plugininfo\qtype::get_enabled_plugins();
813
        $this->assertArrayHasKey('truefalse', $enabledplugins);
814
    }
1441 ariadna 815
 
816
    /**
817
     * Test apply_preset for a deprecated plugin type.
818
     *
819
     * @runInSeparateProcess
820
     *
821
     * @covers ::apply_preset
822
     * @return void
823
     */
824
    public function test_apply_preset_deprecated_plugintype(): void {
825
        global $CFG;
826
        $this->resetAfterTest();
827
 
828
        // Create a preset.
829
        $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
830
        $presetid = $generator->create_preset();
831
 
832
        // Add a mock plugin into the preset. This plugin will be mocked and deprecated below.
833
        helper::add_plugin($presetid, 'fake', 'fullfeatured', true);
834
 
835
        // Inject the mock plugin type + plugin, and deprecate it.
836
        $this->add_mocked_plugintype('fake', "$CFG->libdir/tests/fixtures/fakeplugins/fake", true);
837
        $this->add_mocked_plugin('fake', 'fullfeatured', $CFG->libdir . '/tests/fixtures/fakeplugins/fake/fullfeatured');
838
 
839
        // Pre-flight check to ensure that the plugin is deprecated.
840
        $pluginman = \core\plugin_manager::instance();
841
        $plugininfo = $pluginman->get_plugin_info('fake_fullfeatured');
842
        // Expected, unit-test-only debugging, since \core\plugin_manager isn't aware of the mock plugininfo class for this type.
843
        $this->assertDebuggingCalled();
844
        $this->assertTrue($plugininfo->is_deprecated());
845
 
846
        // Finally, check apply_preset method, verifying the deprecated plugin is skipped.
847
        $manager = new manager();
848
        [$applied, $skipped] = $manager->apply_preset($presetid);
849
        $this->assertdebuggingcalledcount(2); // Expected unit-test-only debugging, as above.
850
        $this->assertContains('fake', array_column($skipped, 'plugin'));
851
    }
1 efrain 852
}