Proyectos de Subversion Moodle

Rev

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