Merge branch 'MDL-60851-master' of git://github.com/damyon/moodle
authorJake Dallimore <jake@moodle.com>
Wed, 1 May 2019 01:32:54 +0000 (09:32 +0800)
committerJake Dallimore <jake@moodle.com>
Wed, 1 May 2019 01:32:54 +0000 (09:32 +0800)
backup/util/settings/setting_dependency.class.php
backup/util/settings/tests/settings_test.php

index 079537f..22ac0ed 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -82,7 +81,7 @@ abstract class setting_dependency {
      * Destroy all circular references. It helps PHP 5.2 a lot!
      */
     public function destroy() {
-        // No need to destroy anything recursively here, direct reset
+        // No need to destroy anything recursively here, direct reset.
         $this->setting = null;
         $this->dependentsetting = null;
     }
@@ -94,16 +93,19 @@ abstract class setting_dependency {
      * @return bool
      */
     final public function process_change($changetype, $oldvalue) {
-        // Check the type of change requested
+        // Check the type of change requested.
         switch ($changetype) {
-            // Process a status change
-            case base_setting::CHANGED_STATUS: return $this->process_status_change($oldvalue);
-            // Process a visibility change
-            case base_setting::CHANGED_VISIBILITY: return $this->process_visibility_change($oldvalue);
-            // Process a value change
-            case base_setting::CHANGED_VALUE: return $this->process_value_change($oldvalue);
+            // Process a status change.
+            case base_setting::CHANGED_STATUS:
+                return $this->process_status_change($oldvalue);
+            // Process a visibility change.
+            case base_setting::CHANGED_VISIBILITY:
+                return $this->process_visibility_change($oldvalue);
+            // Process a value change.
+            case base_setting::CHANGED_VALUE:
+                return $this->process_value_change($oldvalue);
         }
-        // Throw an exception if we get this far
+        // Throw an exception if we get this far.
         throw new backup_ui_exception('unknownchangetype');
     }
     /**
@@ -112,11 +114,11 @@ abstract class setting_dependency {
      * @return bool
      */
     protected function process_visibility_change($oldvisibility) {
-        // Store the current dependent settings visibility for comparison
+        // Store the current dependent settings visibility for comparison.
         $prevalue = $this->dependentsetting->get_visibility();
-        // Set it regardless of whether we need to
+        // Set it regardless of whether we need to.
         $this->dependentsetting->set_visibility($this->setting->get_visibility());
-        // Return true if it changed
+        // Return true if it changed.
         return ($prevalue != $this->dependentsetting->get_visibility());
     }
     /**
@@ -182,15 +184,16 @@ class setting_dependency_disabledif_equals extends setting_dependency {
      */
     public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) {
         parent::__construct($setting, $dependentsetting, $defaultvalue);
-        $this->value = ($value)?(string)$value:0;
+        $this->value = ($value) ? (string)$value : 0;
     }
     /**
      * Returns true if the dependent setting is locked by this setting_dependency.
      * @return bool
      */
     public function is_locked() {
-        // If the setting is locked or the dependent setting should be locked then return true
-        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || $this->setting->get_value() == $this->value) {
+        // If the setting is locked or the dependent setting should be locked then return true.
+        if ($this->setting->get_status() !== base_setting::NOT_LOCKED ||
+                $this->evaluate_disabled_condition($this->setting->get_value())) {
             return true;
         }
         // Else the dependent setting is not locked by this setting_dependency.
@@ -208,17 +211,25 @@ class setting_dependency_disabledif_equals extends setting_dependency {
             return false;
         }
         $prevalue = $this->dependentsetting->get_value();
-        // If the setting is the desired value enact the dependency
-        if ($this->setting->get_value() == $this->value) {
+        // If the setting is the desired value enact the dependency.
+        $settingvalue = $this->setting->get_value();
+        if ($this->evaluate_disabled_condition($settingvalue)) {
             // The dependent setting needs to be locked by hierachy and set to the
             // default value.
             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
-            $this->dependentsetting->set_value($this->defaultvalue);
+
+            // For checkboxes the default value is false, but when the setting is
+            // locked, the value should inherit from the parent setting.
+            if ($this->defaultvalue === false) {
+                $this->dependentsetting->set_value($settingvalue);
+            } else {
+                $this->dependentsetting->set_value($this->defaultvalue);
+            }
         } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
-            // We can unlock the dependent setting
+            // We can unlock the dependent setting.
             $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
         }
-        // Return true if the value has changed for the dependent setting
+        // Return true if the value has changed for the dependent setting.
         return ($prevalue != $this->dependentsetting->get_value());
     }
     /**
@@ -227,17 +238,18 @@ class setting_dependency_disabledif_equals extends setting_dependency {
      * @return bool
      */
     protected function process_status_change($oldstatus) {
-        // Store the dependent status
+        // Store the dependent status.
         $prevalue = $this->dependentsetting->get_status();
-        // Store the current status
+        // Store the current status.
         $currentstatus = $this->setting->get_status();
         if ($currentstatus == base_setting::NOT_LOCKED) {
-            if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && $this->setting->get_value() != $this->value) {
-                // Dependency has changes, is not fine, unlock the dependent setting
+            if ($prevalue == base_setting::LOCKED_BY_HIERARCHY &&
+                    !$this->evaluate_disabled_condition($this->setting->get_value())) {
+                // Dependency has changes, is not fine, unlock the dependent setting.
                 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
             }
         } else {
-            // Make sure the dependent setting is also locked, in this case by hierarchy
+            // Make sure the dependent setting is also locked, in this case by hierarchy.
             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
         }
         // Return true if the dependent setting has changed.
@@ -248,17 +260,17 @@ class setting_dependency_disabledif_equals extends setting_dependency {
      * @return bool True if there were changes
      */
     public function enforce() {
-        // This will be set to true if ANYTHING changes
+        // This will be set to true if ANYTHING changes.
         $changes = false;
-        // First process any value changes
+        // First process any value changes.
         if ($this->process_value_change($this->setting->get_value())) {
             $changes = true;
         }
-        // Second process any status changes
+        // Second process any status changes.
         if ($this->process_status_change($this->setting->get_status())) {
             $changes = true;
         }
-        // Finally process visibility changes
+        // Finally process visibility changes.
         if ($this->process_visibility_change($this->setting->get_visibility())) {
             $changes = true;
         }
@@ -271,152 +283,72 @@ class setting_dependency_disabledif_equals extends setting_dependency {
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'eq',
-            'value'=>$this->value
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'eq',
+            'value' => $this->value
         );
     }
+
+    /**
+     * Evaluate the current value of the setting and return true if the dependent setting should be locked or false.
+     * This function should be abstract, but there will probably be existing sub-classes so we must provide a default
+     * implementation.
+     * @param mixed $value The value of the parent setting.
+     * @return bool
+     */
+    protected function evaluate_disabled_condition($value) {
+        return $value == $this->value;
+    }
 }
 
 /**
-* A dependency that disables the secondary setting if the primary setting is
-* not equal to the provided value
-*
-* @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * A dependency that disables the secondary setting if the primary setting is
+ * not equal to the provided value
+ *
+ * @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals {
+
     /**
-    * Enforces the dependency if required.
-    * @return bool True if there were changes
-    */
-    public function enforce() {
-        // This will be set to true if ANYTHING changes
-        $changes = false;
-        // First process any value changes
-        if (!$this->process_value_change($this->setting->get_value())) {
-            $changes = true;
-        }
-        // Second process any status changes
-        if ($this->process_status_change($this->setting->get_status())) {
-            $changes = true;
-        }
-        // Finally process visibility changes
-        if ($this->process_visibility_change($this->setting->get_visibility())) {
-            $changes = true;
-        }
-        return $changes;
+     * Evaluate the current value of the setting and return true if the dependent setting should be locked or false.
+     * @param mixed $value The value of the parent setting.
+     * @return bool
+     */
+    protected function evaluate_disabled_condition($value) {
+        return $value != $this->value;
     }
+
     /**
-    * Returns an array of properties suitable to be used to define a moodleforms
-    * disabled command
-    * @return array
-    */
+     * Returns an array of properties suitable to be used to define a moodleforms
+     * disabled command
+     * @return array
+     */
     public function get_moodleform_properties() {
         return array(
-                'setting'=>$this->dependentsetting->get_ui_name(),
-                'dependenton'=>$this->setting->get_ui_name(),
-                'condition'=>'notequal',
-                'value'=>$this->value
+                'setting' => $this->dependentsetting->get_ui_name(),
+                'dependenton' => $this->setting->get_ui_name(),
+                'condition' => 'notequal',
+                'value' => $this->value
         );
     }
 }
 
-//with array
-class setting_dependency_disabledif_equals2 extends setting_dependency {
-    /**
-     * The value to compare to
-     * @var mixed
-     */
-    protected $value;
-    /**
-     * Creates the dependency
-     *
-     * @param base_setting $setting
-     * @param base_setting $dependentsetting
-     * @param mixed $value
-     * @param mixed $defaultvalue
-     */
-    public function __construct(base_setting $setting, base_setting $dependentsetting, array $value, $defaultvalue = false) {
-        parent::__construct($setting, $dependentsetting, $defaultvalue);
-        $this->value = $value;
-    }
-    /**
-     * Returns true if the dependent setting is locked by this setting_dependency.
-     * @return bool
-     */
-    public function is_locked() {
-        // If the setting is locked or the dependent setting should be locked then return true
-        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || in_array($this->setting->get_value(), $this->value)) {
-            return true;
-        }
-        // Else the dependent setting is not locked by this setting_dependency.
-        return false;
-    }
-    /**
-     * Processes a value change in the primary setting
-     * @param mixed $oldvalue
-     * @return bool
-     */
-    protected function process_value_change($oldvalue) {
-        $prevalue = $this->dependentsetting->get_value();
-        // If the setting is the desired value enact the dependency
-        if (in_array($this->setting->get_value(), $this->value)) {
-            // The dependent setting needs to be locked by hierachy and set to the
-            // default value.
-            $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
-            $this->dependentsetting->set_value($this->defaultvalue);
-        } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
-            // We can unlock the dependent setting
-            $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
-        }
-        // Return true if the value has changed for the dependent setting
-        return ($prevalue != $this->dependentsetting->get_value());
-    }
+/**
+ * Disable if a value is in a list.
+ */
+class setting_dependency_disabledif_in_array extends setting_dependency_disabledif_equals {
+
     /**
-     * Processes a status change in the primary setting
-     * @param mixed $oldstatus
+     * Evaluate the current value of the setting and return true if the dependent setting should be locked or false.
+     * @param mixed $value The value of the parent setting.
      * @return bool
      */
-    protected function process_status_change($oldstatus) {
-        // Store the dependent status
-        $prevalue = $this->dependentsetting->get_status();
-        // Store the current status
-        $currentstatus = $this->setting->get_status();
-        if ($currentstatus == base_setting::NOT_LOCKED) {
-            if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && !in_array($this->setting->get_value(), $this->value)) {
-                // Dependency has changes, is not fine, unlock the dependent setting
-                $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
-            }
-        } else {
-            // Make sure the dependent setting is also locked, in this case by hierarchy
-            $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
-        }
-        // Return true if the dependent setting has changed.
-        return ($prevalue != $this->dependentsetting->get_status());
-    }
-    /**
-     * Enforces the dependency if required.
-     * @return bool True if there were changes
-     */
-    public function enforce() {
-        // This will be set to true if ANYTHING changes
-        $changes = false;
-        // First process any value changes
-        if ($this->process_value_change($this->setting->get_value())) {
-            $changes = true;
-        }
-        // Second process any status changes
-        if ($this->process_status_change($this->setting->get_status())) {
-            $changes = true;
-        }
-        // Finally process visibility changes
-        if ($this->process_visibility_change($this->setting->get_visibility())) {
-            $changes = true;
-        }
-        return $changes;
+    protected function evaluate_disabled_condition($value) {
+        return in_array($value, $this->value);
     }
+
     /**
      * Returns an array of properties suitable to be used to define a moodleforms
      * disabled command
@@ -424,14 +356,19 @@ class setting_dependency_disabledif_equals2 extends setting_dependency {
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'eq',
-            'value'=>$this->value
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'eq',
+            'value' => $this->value
         );
     }
 }
 
+/**
+ * This class is here for backwards compatibility (terrible name).
+ */
+class setting_dependency_disabledif_equals2 extends setting_dependency_disabledif_in_array {
+}
 
 /**
  * A dependency that disables the secondary element if the primary element is
@@ -452,9 +389,9 @@ class setting_dependency_disabledif_checked extends setting_dependency_disabledi
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'checked'
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'checked'
         );
     }
 }
@@ -478,9 +415,9 @@ class setting_dependency_disabledif_not_checked extends setting_dependency_disab
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'notchecked'
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'notchecked'
         );
     }
 }
@@ -497,6 +434,16 @@ class setting_dependency_disabledif_not_empty extends setting_dependency_disable
         parent::__construct($setting, $dependentsetting, false, $defaultvalue);
         $this->value = false;
     }
+
+    /**
+     * Evaluate the current value of the setting and return true if the dependent setting should be locked or false.
+     * @param mixed $value The value of the parent setting.
+     * @return bool
+     */
+    protected function evaluate_disabled_condition($value) {
+        return !empty($value);
+    }
+
     /**
      * Returns an array of properties suitable to be used to define a moodleforms
      * disabled command
@@ -504,50 +451,12 @@ class setting_dependency_disabledif_not_empty extends setting_dependency_disable
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'notequal',
-            'value'=>''
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'notequal',
+            'value' => ''
         );
     }
-    /**
-     * Processes a value change in the primary setting
-     * @param mixed $oldvalue
-     * @return bool
-     */
-    protected function process_value_change($oldvalue) {
-        $prevalue = $this->dependentsetting->get_value();
-        // If the setting is the desired value enact the dependency
-        $value = $this->setting->get_value();
-        if (!empty($value)) {
-            // The dependent setting needs to be locked by hierachy and set to the
-            // default value.
-            $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
-            if ($this->defaultvalue === false) {
-                $this->dependentsetting->set_value($value);
-            } else {
-                $this->dependentsetting->set_value($this->defaultvalue);
-            }
-        } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
-            // We can unlock the dependent setting
-            $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
-        }
-        // Return true if the value has changed for the dependent setting
-        return ($prevalue != $this->dependentsetting->get_value());
-    }
-
-    /**
-     * Returns true if the dependent setting is locked by this setting_dependency.
-     * @return bool
-     */
-    public function is_locked() {
-        // If the setting is locked or the dependent setting should be locked then return true
-        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || !empty($value)) {
-            return true;
-        }
-        // Else the dependent setting is not locked by this setting_dependency.
-        return false;
-    }
 }
 
 /**
@@ -562,6 +471,16 @@ class setting_dependency_disabledif_empty extends setting_dependency_disabledif_
         parent::__construct($setting, $dependentsetting, false, $defaultvalue);
         $this->value = false;
     }
+
+    /**
+     * Evaluate the current value of the setting and return true if the dependent setting should be locked or false.
+     * @param mixed $value The value of the parent setting.
+     * @return bool
+     */
+    protected function evaluate_disabled_condition($value) {
+        return empty($value);
+    }
+
     /**
      * Returns an array of properties suitable to be used to define a moodleforms
      * disabled command
@@ -569,47 +488,10 @@ class setting_dependency_disabledif_empty extends setting_dependency_disabledif_
      */
     public function get_moodleform_properties() {
         return array(
-            'setting'=>$this->dependentsetting->get_ui_name(),
-            'dependenton'=>$this->setting->get_ui_name(),
-            'condition'=>'notequal',
-            'value'=>''
+            'setting' => $this->dependentsetting->get_ui_name(),
+            'dependenton' => $this->setting->get_ui_name(),
+            'condition' => 'notequal',
+            'value' => ''
         );
     }
-    /**
-     * Processes a value change in the primary setting
-     * @param mixed $oldvalue
-     * @return bool
-     */
-    protected function process_value_change($oldvalue) {
-        $prevalue = $this->dependentsetting->get_value();
-        // If the setting is the desired value enact the dependency
-        $value = $this->setting->get_value();
-        if (empty($value)) {
-            // The dependent setting needs to be locked by hierachy and set to the
-            // default value.
-            $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
-            if ($this->defaultvalue === false) {
-                $this->dependentsetting->set_value($value);
-            } else {
-                $this->dependentsetting->set_value($this->defaultvalue);
-            }
-        } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
-            // We can unlock the dependent setting
-            $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
-        }
-        // Return true if the value has changed for the dependent setting
-        return ($prevalue != $this->dependentsetting->get_value());
-    }
-    /**
-     * Returns true if the dependent setting is locked by this setting_dependency.
-     * @return bool
-     */
-    public function is_locked() {
-        // If the setting is locked or the dependent setting should be locked then return true
-        if ($this->setting->get_status() !== base_setting::NOT_LOCKED || empty($value)) {
-            return true;
-        }
-        // Else the dependent setting is not locked by this setting_dependency.
-        return false;
-    }
 }
index 45bc4ec..63999fe 100644 (file)
@@ -45,7 +45,7 @@ class backp_settings_testcase extends basic_testcase {
     /**
      * test base_setting class
      */
-    function test_base_setting() {
+    public function test_base_setting() {
         // Instantiate base_setting and check everything
         $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN);
         $this->assertTrue($bs instanceof base_setting);
@@ -290,10 +290,54 @@ class backp_settings_testcase extends basic_testcase {
         $this->assertEquals($ubs3->get_status(), $ubs1->get_status());
     }
 
+    /**
+     * Test that locked and unlocked states on dependent backup settings at the same level
+     * correctly do not flow from the parent to the child setting when the setting is locked by permissions.
+     */
+    public function test_dependency_empty_locked_by_permission_child_is_not_unlocked() {
+        // Check dependencies are working ok.
+        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 2);
+        $bs1->set_level(1);
+        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 2);
+        $bs2->set_level(1); // Same level *must* work.
+        $bs1->add_dependency($bs2, setting_dependency::DISABLED_EMPTY);
+
+        $bs1->set_status(base_setting::LOCKED_BY_PERMISSION);
+        $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status());
+        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status());
+        $bs2->set_status(base_setting::LOCKED_BY_PERMISSION);
+        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs1->get_status());
+
+        // Unlocking the parent should NOT unlock the child.
+        $bs1->set_status(base_setting::NOT_LOCKED);
+
+        $this->assertEquals(base_setting::LOCKED_BY_PERMISSION, $bs2->get_status());
+    }
+
+    /**
+     * Test that locked and unlocked states on dependent backup settings at the same level
+     * correctly do flow from the parent to the child setting when the setting is locked by config.
+     */
+    public function test_dependency_not_empty_locked_by_config_parent_is_unlocked() {
+        $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, 0);
+        $bs1->set_level(1);
+        $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, 0);
+        $bs2->set_level(1); // Same level *must* work.
+        $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY);
+
+        $bs1->set_status(base_setting::LOCKED_BY_CONFIG);
+        $this->assertEquals(base_setting::LOCKED_BY_HIERARCHY, $bs2->get_status());
+        $this->assertEquals(base_setting::LOCKED_BY_CONFIG, $bs1->get_status());
+
+        // Unlocking the parent should unlock the child.
+        $bs1->set_status(base_setting::NOT_LOCKED);
+        $this->assertEquals(base_setting::NOT_LOCKED, $bs2->get_status());
+    }
+
     /**
      * test backup_setting class
      */
-    function test_backup_setting() {
+    public function test_backup_setting() {
         // Instantiate backup_setting class and set level
         $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null);
         $bs->set_level(1);
@@ -340,7 +384,7 @@ class backp_settings_testcase extends basic_testcase {
     /**
      * test activity_backup_setting class
      */
-    function test_activity_backup_setting() {
+    public function test_activity_backup_setting() {
         $bs = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null);
         $this->assertEquals($bs->get_level(), backup_setting::ACTIVITY_LEVEL);
 
@@ -355,7 +399,7 @@ class backp_settings_testcase extends basic_testcase {
     /**
      * test section_backup_setting class
      */
-    function test_section_backup_setting() {
+    public function test_section_backup_setting() {
         $bs = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null);
         $this->assertEquals($bs->get_level(), backup_setting::SECTION_LEVEL);
 
@@ -370,7 +414,7 @@ class backp_settings_testcase extends basic_testcase {
     /**
      * test course_backup_setting class
      */
-    function test_course_backup_setting() {
+    public function test_course_backup_setting() {
         $bs = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null);
         $this->assertEquals($bs->get_level(), backup_setting::COURSE_LEVEL);