[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/backup/util/settings/tests/ -> settings_test.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1