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
/**
18
 * Setting tests (all).
19
 *
20
 * @package   core_backup
21
 * @category  test
22
 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
23
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace core_backup;
27
 
28
use activity_backup_setting;
29
use backup_setting;
30
use backup_setting_exception;
31
use base_setting;
32
use base_setting_exception;
33
use course_backup_setting;
34
use section_backup_setting;
35
use setting_dependency;
36
use setting_dependency_disabledif_empty;
37
 
38
defined('MOODLE_INTERNAL') || die();
39
 
40
// Include all the needed stuff
41
global $CFG;
42
require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php');
43
require_once($CFG->dirroot . '/backup/backup.class.php');
44
require_once($CFG->dirroot . '/backup/util/settings/base_setting.class.php');
45
require_once($CFG->dirroot . '/backup/util/settings/backup_setting.class.php');
46
require_once($CFG->dirroot . '/backup/util/settings/setting_dependency.class.php');
47
require_once($CFG->dirroot . '/backup/util/settings/root/root_backup_setting.class.php');
48
require_once($CFG->dirroot . '/backup/util/settings/activity/activity_backup_setting.class.php');
49
require_once($CFG->dirroot . '/backup/util/settings/section/section_backup_setting.class.php');
50
require_once($CFG->dirroot . '/backup/util/settings/course/course_backup_setting.class.php');
51
require_once($CFG->dirroot . '/backup/util/ui/backup_ui_setting.class.php');
52
 
53
/**
54
 * Setting tests (all).
55
 *
56
 * @package   core_backup
57
 * @category  test
58
 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
59
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
60
 */
61
class settings_test extends \basic_testcase {
62
 
63
    /**
64
     * test base_setting class
65
     */
11 efrain 66
    public function test_base_setting(): void {
1 efrain 67
        // Instantiate base_setting and check everything
68
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
69
        $this->assertTrue($bs instanceof base_setting);
70
        $this->assertEquals($bs->get_name(), 'test');
71
        $this->assertEquals($bs->get_vtype(), base_setting::IS_BOOLEAN);
72
        $this->assertTrue(is_null($bs->get_value()));
73
        $this->assertEquals($bs->get_visibility(), base_setting::VISIBLE);
74
        $this->assertEquals($bs->get_status(), base_setting::NOT_LOCKED);
75
 
76
        // Instantiate base_setting with explicit nulls
77
        $bs = new mock_base_setting('test', base_setting::IS_FILENAME, 'filename.txt', null, null);
78
        $this->assertEquals($bs->get_value() , 'filename.txt');
79
        $this->assertEquals($bs->get_visibility(), base_setting::VISIBLE);
80
        $this->assertEquals($bs->get_status(), base_setting::NOT_LOCKED);
81
 
82
        // Instantiate base_setting and set value, visibility and status
83
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
84
        $bs->set_value(true);
85
        $this->assertNotEmpty($bs->get_value());
86
        $bs->set_visibility(base_setting::HIDDEN);
87
        $this->assertEquals($bs->get_visibility(), base_setting::HIDDEN);
88
        $bs->set_status(base_setting::LOCKED_BY_HIERARCHY);
89
        $this->assertEquals($bs->get_status(), base_setting::LOCKED_BY_HIERARCHY);
90
 
91
        // Instantiate with wrong vtype
92
        try {
93
            $bs = new mock_base_setting('test', 'one_wrong_type');
94
            $this->assertTrue(false, 'base_setting_exception expected');
95
        } catch (\Exception $e) {
96
            $this->assertTrue($e instanceof base_setting_exception);
97
            $this->assertEquals($e->errorcode, 'setting_invalid_type');
98
        }
99
 
100
        // Instantiate with wrong integer value
101
        try {
102
            $bs = new mock_base_setting('test', base_setting::IS_INTEGER, 99.99);
103
            $this->assertTrue(false, 'base_setting_exception expected');
104
        } catch (\Exception $e) {
105
            $this->assertTrue($e instanceof base_setting_exception);
106
            $this->assertEquals($e->errorcode, 'setting_invalid_integer');
107
        }
108
 
109
        // Instantiate with wrong filename value
110
        try {
111
            $bs = new mock_base_setting('test', base_setting::IS_FILENAME, '../../filename.txt');
112
            $this->assertTrue(false, 'base_setting_exception expected');
113
        } catch (\Exception $e) {
114
            $this->assertTrue($e instanceof base_setting_exception);
115
            $this->assertEquals($e->errorcode, 'setting_invalid_filename');
116
        }
117
 
118
        // Instantiate with wrong visibility
119
        try {
120
            $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, 'one_wrong_visibility');
121
            $this->assertTrue(false, 'base_setting_exception expected');
122
        } catch (\Exception $e) {
123
            $this->assertTrue($e instanceof base_setting_exception);
124
            $this->assertEquals($e->errorcode, 'setting_invalid_visibility');
125
        }
126
 
127
        // Instantiate with wrong status
128
        try {
129
            $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, 'one_wrong_status');
130
            $this->assertTrue(false, 'base_setting_exception expected');
131
        } catch (\Exception $e) {
132
            $this->assertTrue($e instanceof base_setting_exception);
133
            $this->assertEquals($e->errorcode, 'setting_invalid_status');
134
        }
135
 
136
        // Instantiate base_setting and try to set wrong ui_type
137
        // We need a custom error handler to catch the type hinting error
138
        // that should return incorrect_object_passed
139
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
140
        set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR);
141
        try {
142
            $bs->set_ui('one_wrong_ui_type', 'label', array(), array());
143
            $this->assertTrue(false, 'base_setting_exception expected');
144
        } catch (\Exception $e) {
145
            $this->assertTrue($e instanceof base_setting_exception);
146
            $this->assertEquals($e->errorcode, 'incorrect_object_passed');
147
        } catch (\TypeError $e) {
148
            // On PHP7+ we get a TypeError raised, lets check we've the right error.
149
            $this->assertMatchesRegularExpression('/must be (of type|an instance of) backup_setting_ui/', $e->getMessage());
150
        }
151
        restore_error_handler();
152
 
153
        // Instantiate base_setting and try to set wrong ui_label
154
        // We need a custom error handler to catch the type hinting error
155
        // that should return incorrect_object_passed
156
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
157
        set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR);
158
        try {
159
            $bs->set_ui(base_setting::UI_HTML_CHECKBOX, 'one/wrong/label', array(), array());
160
            $this->assertTrue(false, 'base_setting_exception expected');
161
        } catch (\Exception $e) {
162
            $this->assertTrue($e instanceof base_setting_exception);
163
            $this->assertEquals($e->errorcode, 'incorrect_object_passed');
164
        } catch (\TypeError $e) {
165
            // On PHP7+ we get a TypeError raised, lets check we've the right error.
166
            $this->assertMatchesRegularExpression('/must be (of type|an instance of) backup_setting_ui/', $e->getMessage());
167
        }
168
        restore_error_handler();
169
 
170
        // Try to change value of locked setting by permission
171
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_PERMISSION);
172
        try {
173
            $bs->set_value(true);
174
            $this->assertTrue(false, 'base_setting_exception expected');
175
        } catch (\Exception $e) {
176
            $this->assertTrue($e instanceof base_setting_exception);
177
            $this->assertEquals($e->errorcode, 'setting_locked_by_permission');
178
        }
179
 
180
        // Try to change value of locked setting by config
181
        $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_CONFIG);
182
        try {
183
            $bs->set_value(true);
184
            $this->assertTrue(false, 'base_setting_exception expected');
185
        } catch (\Exception $e) {
186
            $this->assertTrue($e instanceof base_setting_exception);
187
            $this->assertEquals($e->errorcode, 'setting_locked_by_config');
188
        }
189
 
190
        // Try to add same setting twice
191
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
192
        $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null);
193
        $bs1->add_dependency($bs2, null, array('value'=>0));
194
        try {
195
            $bs1->add_dependency($bs2);
196
            $this->assertTrue(false, 'base_setting_exception expected');
197
        } catch (\Exception $e) {
198
            $this->assertTrue($e instanceof base_setting_exception);
199
            $this->assertEquals($e->errorcode, 'setting_already_added');
200
        }
201
 
202
        // Try to create one circular reference
203
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
204
        try {
205
            $bs1->add_dependency($bs1); // self
206
            $this->assertTrue(false, 'base_setting_exception expected');
207
        } catch (\Exception $e) {
208
            $this->assertTrue($e instanceof base_setting_exception);
209
            $this->assertEquals($e->errorcode, 'setting_circular_reference');
210
            $this->assertTrue($e->a instanceof \stdClass);
211
            $this->assertEquals($e->a->main, 'test1');
212
            $this->assertEquals($e->a->alreadydependent, 'test1');
213
        }
214
 
215
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
216
        $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null);
217
        $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null);
218
        $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null);
219
        $bs1->add_dependency($bs2, null, array('value'=>0));
220
        $bs2->add_dependency($bs3, null, array('value'=>0));
221
        $bs3->add_dependency($bs4, null, array('value'=>0));
222
        try {
223
            $bs4->add_dependency($bs1, null, array('value'=>0));
224
            $this->assertTrue(false, 'base_setting_exception expected');
225
        } catch (\Exception $e) {
226
            $this->assertTrue($e instanceof base_setting_exception);
227
            $this->assertEquals($e->errorcode, 'setting_circular_reference');
228
            $this->assertTrue($e->a instanceof \stdClass);
229
            $this->assertEquals($e->a->main, 'test1');
230
            $this->assertEquals($e->a->alreadydependent, 'test4');
231
        }
232
 
233
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
234
        $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null);
235
        $bs1->register_dependency(new setting_dependency_disabledif_empty($bs1, $bs2));
236
        try {
237
            // $bs1 is already dependent on $bs2 so this should fail.
238
            $bs2->register_dependency(new setting_dependency_disabledif_empty($bs2, $bs1));
239
            $this->assertTrue(false, 'base_setting_exception expected');
240
        } catch (\Exception $e) {
241
            $this->assertTrue($e instanceof base_setting_exception);
242
            $this->assertEquals($e->errorcode, 'setting_circular_reference');
243
            $this->assertTrue($e->a instanceof \stdClass);
244
            $this->assertEquals($e->a->main, 'test1');
245
            $this->assertEquals($e->a->alreadydependent, 'test2');
246
        }
247
 
248
        // Create 3 settings and observe between them, last one must
249
        // automatically inherit all the settings defined in the main one
250
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
251
        $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null);
252
        $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null);
253
        $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY);
254
        $bs2->add_dependency($bs3, setting_dependency::DISABLED_NOT_EMPTY);
255
        // Check values are spreaded ok
256
        $bs1->set_value(123);
257
        $this->assertEquals($bs1->get_value(), 123);
258
        $this->assertEquals($bs2->get_value(), $bs1->get_value());
259
        $this->assertEquals($bs3->get_value(), $bs1->get_value());
260
 
261
        // Add one more setting and set value again
262
        $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null);
263
        $bs2->add_dependency($bs4, setting_dependency::DISABLED_NOT_EMPTY);
264
        $bs2->set_value(321);
265
        // The above change should change
266
        $this->assertEquals($bs1->get_value(), 123);
267
        $this->assertEquals($bs2->get_value(), 321);
268
        $this->assertEquals($bs3->get_value(), 321);
269
        $this->assertEquals($bs4->get_value(), 321);
270
 
271
        // Check visibility is spreaded ok
272
        $bs1->set_visibility(base_setting::HIDDEN);
273
        $this->assertEquals($bs2->get_visibility(), $bs1->get_visibility());
274
        $this->assertEquals($bs3->get_visibility(), $bs1->get_visibility());
275
        // Check status is spreaded ok
276
        $bs1->set_status(base_setting::LOCKED_BY_HIERARCHY);
277
        $this->assertEquals($bs2->get_status(), $bs1->get_status());
278
        $this->assertEquals($bs3->get_status(), $bs1->get_status());
279
 
280
        // Create 3 settings and observe between them, put them in one array,
281
        // force serialize/deserialize to check the observable pattern continues
282
        // working after that
283
        $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null);
284
        $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null);
285
        $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null);
286
        $bs1->add_dependency($bs2, null, array('value'=>0));
287
        $bs2->add_dependency($bs3, null, array('value'=>0));
288
        // Serialize
289
        $arr = array($bs1, $bs2, $bs3);
290
        $ser = base64_encode(serialize($arr));
291
        // Unserialize and copy to new objects
292
        $newarr = unserialize(base64_decode($ser));
293
        $ubs1 = $newarr[0];
294
        $ubs2 = $newarr[1];
295
        $ubs3 = $newarr[2];
296
        // Must continue being base settings
297
        $this->assertTrue($ubs1 instanceof base_setting);
298
        $this->assertTrue($ubs2 instanceof base_setting);
299
        $this->assertTrue($ubs3 instanceof base_setting);
300
        // Set parent setting
301
        $ubs1->set_value(1234);
302
        $ubs1->set_visibility(base_setting::HIDDEN);
303
        $ubs1->set_status(base_setting::LOCKED_BY_HIERARCHY);
304
        // Check changes have been spreaded
305
        $this->assertEquals($ubs2->get_visibility(), $ubs1->get_visibility());
306
        $this->assertEquals($ubs3->get_visibility(), $ubs1->get_visibility());
307
        $this->assertEquals($ubs2->get_status(), $ubs1->get_status());
308
        $this->assertEquals($ubs3->get_status(), $ubs1->get_status());
309
    }
310
 
311
    /**
312
     * Test that locked and unlocked states on dependent backup settings at the same level
313
     * correctly do not flow from the parent to the child setting when the setting is locked by permissions.
314
     */
11 efrain 315
    public function test_dependency_empty_locked_by_permission_child_is_not_unlocked(): void {
1 efrain 316
        // Check dependencies are working ok.
317
        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 2);
318
        $bs1->set_level(1);
319
        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 2);
320
        $bs2->set_level(1); // Same level *must* work.
321
        $bs1->add_dependency($bs2, setting_dependency::DISABLED_EMPTY);
322
 
323
        $bs1->set_status(base_setting::LOCKED_BY_PERMISSION);
324
        $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status());
325
        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status());
326
        $bs2->set_status(base_setting::LOCKED_BY_PERMISSION);
327
        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status());
328
 
329
        // Unlocking the parent should NOT unlock the child.
330
        $bs1->set_status(base_setting::NOT_LOCKED);
331
 
332
        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs2->get_status());
333
    }
334
 
335
    /**
336
     * Test that locked and unlocked states on dependent backup settings at the same level
337
     * correctly do flow from the parent to the child setting when the setting is locked by config.
338
     */
11 efrain 339
    public function test_dependency_not_empty_locked_by_config_parent_is_unlocked(): void {
1 efrain 340
        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 0);
341
        $bs1->set_level(1);
342
        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 0);
343
        $bs2->set_level(1); // Same level *must* work.
344
        $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY);
345
 
346
        $bs1->set_status(base_setting::LOCKED_BY_CONFIG);
347
        $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status());
348
        $this->assertEquals(base_setting::LOCKED_BY_CONFIG, $bs1->get_status());
349
 
350
        // Unlocking the parent should unlock the child.
351
        $bs1->set_status(base_setting::NOT_LOCKED);
352
        $this->assertEquals(base_setting::NOT_LOCKED, $bs2->get_status());
353
    }
354
 
355
    /**
356
     * test backup_setting class
357
     */
11 efrain 358
    public function test_backup_setting(): void {
1 efrain 359
        // Instantiate backup_setting class and set level
360
        $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null);
361
        $bs->set_level(1);
362
        $this->assertEquals($bs->get_level(), 1);
363
 
364
        // Instantiate backup setting class and try to add one non backup_setting dependency
365
        set_error_handler('\core_backup\backup_setting_error_handler', E_RECOVERABLE_ERROR);
366
        $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null);
367
        try {
368
            $bs->add_dependency(new \stdClass());
369
            $this->assertTrue(false, 'backup_setting_exception expected');
370
        } catch (\Exception $e) {
371
            $this->assertTrue($e instanceof backup_setting_exception);
372
            $this->assertEquals($e->errorcode, 'incorrect_object_passed');
373
        } catch (\TypeError $e) {
374
            // On PHP7+ we get a TypeError raised, lets check we've the right error.
375
            $this->assertMatchesRegularExpression('/must be (an instance of|of type) base_setting/', $e->getMessage());
376
        }
377
        restore_error_handler();
378
 
379
        // Try to assing upper level dependency
380
        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null);
381
        $bs1->set_level(1);
382
        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null);
383
        $bs2->set_level(2);
384
        try {
385
            $bs2->add_dependency($bs1);
386
            $this->assertTrue(false, 'backup_setting_exception expected');
387
        } catch (\Exception $e) {
388
            $this->assertTrue($e instanceof backup_setting_exception);
389
            $this->assertEquals($e->errorcode, 'cannot_add_upper_level_dependency');
390
        }
391
 
392
        // Check dependencies are working ok
393
        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null);
394
        $bs1->set_level(1);
395
        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null);
396
        $bs2->set_level(1); // Same level *must* work
397
        $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY);
398
        $bs1->set_value(123456);
399
        $this->assertEquals($bs2->get_value(), $bs1->get_value());
400
    }
401
 
402
    /**
403
     * test activity_backup_setting class
404
     */
11 efrain 405
    public function test_activity_backup_setting(): void {
1 efrain 406
        $bs = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null);
407
        $this->assertEquals($bs->get_level(), backup_setting::ACTIVITY_LEVEL);
408
 
409
        // Check checksum implementation is working
410
        $bs1 = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null);
411
        $bs1->set_value(123);
412
        $checksum = $bs1->calculate_checksum();
413
        $this->assertNotEmpty($checksum);
414
        $this->assertTrue($bs1->is_checksum_correct($checksum));
415
    }
416
 
417
    /**
418
     * test section_backup_setting class
419
     */
11 efrain 420
    public function test_section_backup_setting(): void {
1 efrain 421
        $bs = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null);
422
        $this->assertEquals($bs->get_level(), backup_setting::SECTION_LEVEL);
423
 
424
        // Check checksum implementation is working
425
        $bs1 = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null);
426
        $bs1->set_value(123);
427
        $checksum = $bs1->calculate_checksum();
428
        $this->assertNotEmpty($checksum);
429
        $this->assertTrue($bs1->is_checksum_correct($checksum));
430
    }
431
 
432
    /**
433
     * test course_backup_setting class
434
     */
11 efrain 435
    public function test_course_backup_setting(): void {
1 efrain 436
        $bs = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null);
437
        $this->assertEquals($bs->get_level(), backup_setting::COURSE_LEVEL);
438
 
439
        // Check checksum implementation is working
440
        $bs1 = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null);
441
        $bs1->set_value(123);
442
        $checksum = $bs1->calculate_checksum();
443
        $this->assertNotEmpty($checksum);
444
        $this->assertTrue($bs1->is_checksum_correct($checksum));
445
    }
446
}
447
 
448
/**
449
 * helper extended base_setting class that makes some methods public for testing
450
 */
451
class mock_base_setting extends base_setting {
452
    public function get_vtype() {
453
        return $this->vtype;
454
    }
455
 
456
    public function process_change($setting, $ctype, $oldv) {
457
        // Simply, inherit from the main object
458
        $this->set_value($setting->get_value());
459
        $this->set_visibility($setting->get_visibility());
460
        $this->set_status($setting->get_status());
461
    }
462
}
463
 
464
/**
465
 * helper extended backup_setting class that makes some methods public for testing
466
 */
467
class mock_backup_setting extends backup_setting {
468
    public function set_level($level) {
469
        $this->level = $level;
470
    }
471
 
472
    public function process_change($setting, $ctype, $oldv) {
473
        // Simply, inherit from the main object
474
        $this->set_value($setting->get_value());
475
        $this->set_visibility($setting->get_visibility());
476
        $this->set_status($setting->get_status());
477
    }
478
}
479
 
480
/**
481
 * helper extended activity_backup_setting class that makes some methods public for testing
482
 */
483
class mock_activity_backup_setting extends activity_backup_setting {
484
    public function process_change($setting, $ctype, $oldv) {
485
        // Do nothing
486
    }
487
}
488
 
489
/**
490
 * helper extended section_backup_setting class that makes some methods public for testing
491
 */
492
class mock_section_backup_setting extends section_backup_setting {
493
    public function process_change($setting, $ctype, $oldv) {
494
        // Do nothing
495
    }
496
}
497
 
498
/**
499
 * helper extended course_backup_setting class that makes some methods public for testing
500
 */
501
class mock_course_backup_setting extends course_backup_setting {
502
    public function process_change($setting, $ctype, $oldv) {
503
        // Do nothing
504
    }
505
}
506
 
507
/**
508
 * This error handler is used to convert errors to excpetions so that simepltest can
509
 * catch them.
510
 *
511
 * This is required in order to catch type hint mismatches that result in a error
512
 * being thrown. It should only ever be used to catch E_RECOVERABLE_ERROR's.
513
 *
514
 * It throws a backup_setting_exception with 'incorrect_object_passed'
515
 *
516
 * @param int $errno E_RECOVERABLE_ERROR
517
 * @param string $errstr
518
 * @param string $errfile
519
 * @param int $errline
520
 * @return null
521
 */
522
function backup_setting_error_handler($errno, $errstr, $errfile, $errline) {
523
    if ($errno !== E_RECOVERABLE_ERROR) {
524
        // Currently we only want to deal with type hinting errors
525
        return false;
526
    }
527
    throw new backup_setting_exception('incorrect_object_passed');
528
}