|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00025 // Prevent direct access to this file 00026 if (!defined('MOODLE_INTERNAL')) { 00027 die('Direct access to this script is forbidden.'); 00028 } 00029 00030 // Include all the needed stuff 00031 require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); 00032 require_once($CFG->dirroot . '/backup/backup.class.php'); 00033 require_once($CFG->dirroot . '/backup/util/settings/base_setting.class.php'); 00034 require_once($CFG->dirroot . '/backup/util/settings/backup_setting.class.php'); 00035 require_once($CFG->dirroot . '/backup/util/settings/root/root_backup_setting.class.php'); 00036 require_once($CFG->dirroot . '/backup/util/settings/activity/activity_backup_setting.class.php'); 00037 require_once($CFG->dirroot . '/backup/util/settings/section/section_backup_setting.class.php'); 00038 require_once($CFG->dirroot . '/backup/util/settings/course/course_backup_setting.class.php'); 00039 00040 /* 00041 * setting tests (all) 00042 */ 00043 class setting_test extends UnitTestCase { 00044 00045 public static $includecoverage = array('backup/util/settings'); 00046 public static $excludecoverage = array('backup/util/settings/simpletest'); 00047 00048 /* 00049 * test base_setting class 00050 */ 00051 function test_base_setting() { 00052 // Instantiate base_setting and check everything 00053 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); 00054 $this->assertTrue($bs instanceof base_setting); 00055 $this->assertEqual($bs->get_name(), 'test'); 00056 $this->assertEqual($bs->get_vtype(), base_setting::IS_BOOLEAN); 00057 $this->assertTrue(is_null($bs->get_value())); 00058 $this->assertEqual($bs->get_visibility(), base_setting::VISIBLE); 00059 $this->assertEqual($bs->get_status(), base_setting::NOT_LOCKED); 00060 00061 // Instantiate base_setting with explicit nulls 00062 $bs = new mock_base_setting('test', base_setting::IS_FILENAME, 'filename.txt', null, null); 00063 $this->assertEqual($bs->get_value() , 'filename.txt'); 00064 $this->assertEqual($bs->get_visibility(), base_setting::VISIBLE); 00065 $this->assertEqual($bs->get_status(), base_setting::NOT_LOCKED); 00066 00067 // Instantiate base_setting and set value, visibility and status 00068 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); 00069 $bs->set_value(true); 00070 $this->assertTrue($bs->get_value()); 00071 $bs->set_visibility(base_setting::HIDDEN); 00072 $this->assertEqual($bs->get_visibility(), base_setting::HIDDEN); 00073 $bs->set_status(base_setting::LOCKED_BY_HIERARCHY); 00074 $this->assertEqual($bs->get_status(), base_setting::LOCKED_BY_HIERARCHY); 00075 00076 // Instantiate with wrong vtype 00077 try { 00078 $bs = new mock_base_setting('test', 'one_wrong_type'); 00079 $this->assertTrue(false, 'base_setting_exception expected'); 00080 } catch (exception $e) { 00081 $this->assertTrue($e instanceof base_setting_exception); 00082 $this->assertEqual($e->errorcode, 'setting_invalid_type'); 00083 } 00084 00085 // Instantiate with wrong integer value 00086 try { 00087 $bs = new mock_base_setting('test', base_setting::IS_INTEGER, 99.99); 00088 $this->assertTrue(false, 'base_setting_exception expected'); 00089 } catch (exception $e) { 00090 $this->assertTrue($e instanceof base_setting_exception); 00091 $this->assertEqual($e->errorcode, 'setting_invalid_integer'); 00092 } 00093 00094 // Instantiate with wrong filename value 00095 try { 00096 $bs = new mock_base_setting('test', base_setting::IS_FILENAME, '../../filename.txt'); 00097 $this->assertTrue(false, 'base_setting_exception expected'); 00098 } catch (exception $e) { 00099 $this->assertTrue($e instanceof base_setting_exception); 00100 $this->assertEqual($e->errorcode, 'setting_invalid_filename'); 00101 } 00102 00103 // Instantiate with wrong visibility 00104 try { 00105 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, 'one_wrong_visibility'); 00106 $this->assertTrue(false, 'base_setting_exception expected'); 00107 } catch (exception $e) { 00108 $this->assertTrue($e instanceof base_setting_exception); 00109 $this->assertEqual($e->errorcode, 'setting_invalid_visibility'); 00110 } 00111 00112 // Instantiate with wrong status 00113 try { 00114 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, 'one_wrong_status'); 00115 $this->assertTrue(false, 'base_setting_exception expected'); 00116 } catch (exception $e) { 00117 $this->assertTrue($e instanceof base_setting_exception); 00118 $this->assertEqual($e->errorcode, 'setting_invalid_status'); 00119 } 00120 00121 // Instantiate base_setting and try to set wrong ui_type 00122 // We need a custom error handler to catch the type hinting error 00123 // that should return incorrect_object_passed 00124 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); 00125 set_error_handler('backup_setting_error_handler', E_RECOVERABLE_ERROR); 00126 try { 00127 $bs->set_ui('one_wrong_ui_type', 'label', array(), array()); 00128 $this->assertTrue(false, 'base_setting_exception expected'); 00129 } catch (exception $e) { 00130 $this->assertTrue($e instanceof base_setting_exception); 00131 $this->assertEqual($e->errorcode, 'incorrect_object_passed'); 00132 } 00133 restore_error_handler(); 00134 00135 // Instantiate base_setting and try to set wrong ui_label 00136 // We need a custom error handler to catch the type hinting error 00137 // that should return incorrect_object_passed 00138 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN); 00139 set_error_handler('backup_setting_error_handler', E_RECOVERABLE_ERROR); 00140 try { 00141 $bs->set_ui(base_setting::UI_HTML_CHECKBOX, 'one/wrong/label', array(), array()); 00142 $this->assertTrue(false, 'base_setting_exception expected'); 00143 } catch (exception $e) { 00144 $this->assertTrue($e instanceof base_setting_exception); 00145 $this->assertEqual($e->errorcode, 'incorrect_object_passed'); 00146 } 00147 restore_error_handler(); 00148 00149 // Try to change value of locked setting by permission 00150 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_PERMISSION); 00151 try { 00152 $bs->set_value(true); 00153 $this->assertTrue(false, 'base_setting_exception expected'); 00154 } catch (exception $e) { 00155 $this->assertTrue($e instanceof base_setting_exception); 00156 $this->assertEqual($e->errorcode, 'setting_locked_by_permission'); 00157 } 00158 00159 // Try to change value of locked setting by config 00160 $bs = new mock_base_setting('test', base_setting::IS_BOOLEAN, null, null, base_setting::LOCKED_BY_CONFIG); 00161 try { 00162 $bs->set_value(true); 00163 $this->assertTrue(false, 'base_setting_exception expected'); 00164 } catch (exception $e) { 00165 $this->assertTrue($e instanceof base_setting_exception); 00166 $this->assertEqual($e->errorcode, 'setting_locked_by_config'); 00167 } 00168 00169 // Try to add same setting twice 00170 $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); 00171 $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); 00172 $bs1->add_dependency($bs2, null, array('value'=>0)); 00173 try { 00174 $bs1->add_dependency($bs2); 00175 $this->assertTrue(false, 'base_setting_exception expected'); 00176 } catch (exception $e) { 00177 $this->assertTrue($e instanceof base_setting_exception); 00178 $this->assertEqual($e->errorcode, 'setting_already_added'); 00179 } 00180 00181 // Try to create one circular reference 00182 $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); 00183 try { 00184 $bs1->add_dependency($bs1); // self 00185 $this->assertTrue(false, 'base_setting_exception expected'); 00186 } catch (exception $e) { 00187 $this->assertTrue($e instanceof base_setting_exception); 00188 $this->assertEqual($e->errorcode, 'setting_circular_reference'); 00189 $this->assertTrue($e->a instanceof stdclass); 00190 $this->assertEqual($e->a->main, 'test1'); 00191 $this->assertEqual($e->a->alreadydependent, 'test1'); 00192 } 00193 00194 $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); 00195 $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); 00196 $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); 00197 $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null); 00198 $bs1->add_dependency($bs2, null, array('value'=>0)); 00199 $bs2->add_dependency($bs3, null, array('value'=>0)); 00200 $bs3->add_dependency($bs4, null, array('value'=>0)); 00201 try { 00202 $bs4->add_dependency($bs1, null, array('value'=>0)); 00203 $this->assertTrue(false, 'base_setting_exception expected'); 00204 } catch (exception $e) { 00205 $this->assertTrue($e instanceof base_setting_exception); 00206 $this->assertEqual($e->errorcode, 'setting_circular_reference'); 00207 $this->assertTrue($e->a instanceof stdclass); 00208 $this->assertEqual($e->a->main, 'test1'); 00209 $this->assertEqual($e->a->alreadydependent, 'test4'); 00210 } 00211 00212 // Create 3 settings and observe between them, last one must 00213 // automatically inherit all the settings defined in the main one 00214 $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); 00215 $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); 00216 $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); 00217 $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY); 00218 $bs2->add_dependency($bs3, setting_dependency::DISABLED_NOT_EMPTY); 00219 // Check values are spreaded ok 00220 $bs1->set_value(123); 00221 $this->assertEqual($bs1->get_value(), 123); 00222 $this->assertEqual($bs2->get_value(), $bs1->get_value()); 00223 $this->assertEqual($bs3->get_value(), $bs1->get_value()); 00224 00225 // Add one more setting and set value again 00226 $bs4 = new mock_base_setting('test4', base_setting::IS_INTEGER, null); 00227 $bs2->add_dependency($bs4, setting_dependency::DISABLED_NOT_EMPTY); 00228 $bs2->set_value(321); 00229 // The above change should change 00230 $this->assertEqual($bs1->get_value(), 123); 00231 $this->assertEqual($bs2->get_value(), 321); 00232 $this->assertEqual($bs3->get_value(), 321); 00233 $this->assertEqual($bs4->get_value(), 321); 00234 00235 // Check visibility is spreaded ok 00236 $bs1->set_visibility(base_setting::HIDDEN); 00237 $this->assertEqual($bs2->get_visibility(), $bs1->get_visibility()); 00238 $this->assertEqual($bs3->get_visibility(), $bs1->get_visibility()); 00239 // Check status is spreaded ok 00240 $bs1->set_status(base_setting::LOCKED_BY_HIERARCHY); 00241 $this->assertEqual($bs2->get_status(), $bs1->get_status()); 00242 $this->assertEqual($bs3->get_status(), $bs1->get_status()); 00243 00244 // Create 3 settings and observe between them, put them in one array, 00245 // force serialize/deserialize to check the observable pattern continues 00246 // working after that 00247 $bs1 = new mock_base_setting('test1', base_setting::IS_INTEGER, null); 00248 $bs2 = new mock_base_setting('test2', base_setting::IS_INTEGER, null); 00249 $bs3 = new mock_base_setting('test3', base_setting::IS_INTEGER, null); 00250 $bs1->add_dependency($bs2, null, array('value'=>0)); 00251 $bs2->add_dependency($bs3, null, array('value'=>0)); 00252 // Serialize 00253 $arr = array($bs1, $bs2, $bs3); 00254 $ser = base64_encode(serialize($arr)); 00255 // Unserialize and copy to new objects 00256 $newarr = unserialize(base64_decode($ser)); 00257 $ubs1 = $newarr[0]; 00258 $ubs2 = $newarr[1]; 00259 $ubs3 = $newarr[2]; 00260 // Must continue being base settings 00261 $this->assertTrue($ubs1 instanceof base_setting); 00262 $this->assertTrue($ubs2 instanceof base_setting); 00263 $this->assertTrue($ubs3 instanceof base_setting); 00264 // Set parent setting 00265 $ubs1->set_value(1234); 00266 $ubs1->set_visibility(base_setting::HIDDEN); 00267 $ubs1->set_status(base_setting::LOCKED_BY_HIERARCHY); 00268 // Check changes have been spreaded 00269 $this->assertEqual($ubs2->get_visibility(), $ubs1->get_visibility()); 00270 $this->assertEqual($ubs3->get_visibility(), $ubs1->get_visibility()); 00271 $this->assertEqual($ubs2->get_status(), $ubs1->get_status()); 00272 $this->assertEqual($ubs3->get_status(), $ubs1->get_status()); 00273 } 00274 00275 /* 00276 * test backup_setting class 00277 */ 00278 function test_backup_setting() { 00279 // Instantiate backup_setting class and set level 00280 $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null); 00281 $bs->set_level(1); 00282 $this->assertEqual($bs->get_level(), 1); 00283 00284 // Instantiate backup setting class and try to add one non backup_setting dependency 00285 set_error_handler('backup_setting_error_handler', E_RECOVERABLE_ERROR); 00286 $bs = new mock_backup_setting('test', base_setting::IS_INTEGER, null); 00287 try { 00288 $bs->add_dependency(new stdclass()); 00289 $this->assertTrue(false, 'backup_setting_exception expected'); 00290 } catch (exception $e) { 00291 $this->assertTrue($e instanceof backup_setting_exception); 00292 $this->assertEqual($e->errorcode, 'incorrect_object_passed'); 00293 } 00294 restore_error_handler(); 00295 00296 // Try to assing upper level dependency 00297 $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null); 00298 $bs1->set_level(1); 00299 $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null); 00300 $bs2->set_level(2); 00301 try { 00302 $bs2->add_dependency($bs1); 00303 $this->assertTrue(false, 'backup_setting_exception expected'); 00304 } catch (exception $e) { 00305 $this->assertTrue($e instanceof backup_setting_exception); 00306 $this->assertEqual($e->errorcode, 'cannot_add_upper_level_dependency'); 00307 } 00308 00309 // Check dependencies are working ok 00310 $bs1 = new mock_backup_setting('test1', base_setting::IS_INTEGER, null); 00311 $bs1->set_level(1); 00312 $bs2 = new mock_backup_setting('test2', base_setting::IS_INTEGER, null); 00313 $bs2->set_level(1); // Same level *must* work 00314 $bs1->add_dependency($bs2, setting_dependency::DISABLED_NOT_EMPTY); 00315 $bs1->set_value(123456); 00316 $this->assertEqual($bs2->get_value(), $bs1->get_value()); 00317 } 00318 00319 /* 00320 * test activity_backup_setting class 00321 */ 00322 function test_activity_backup_setting() { 00323 $bs = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null); 00324 $this->assertEqual($bs->get_level(), backup_setting::ACTIVITY_LEVEL); 00325 00326 // Check checksum implementation is working 00327 $bs1 = new mock_activity_backup_setting('test', base_setting::IS_INTEGER, null); 00328 $bs1->set_value(123); 00329 $checksum = $bs1->calculate_checksum(); 00330 $this->assertTrue($checksum); 00331 $this->assertTrue($bs1->is_checksum_correct($checksum)); 00332 } 00333 00334 /* 00335 * test section_backup_setting class 00336 */ 00337 function test_section_backup_setting() { 00338 $bs = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null); 00339 $this->assertEqual($bs->get_level(), backup_setting::SECTION_LEVEL); 00340 00341 // Check checksum implementation is working 00342 $bs1 = new mock_section_backup_setting('test', base_setting::IS_INTEGER, null); 00343 $bs1->set_value(123); 00344 $checksum = $bs1->calculate_checksum(); 00345 $this->assertTrue($checksum); 00346 $this->assertTrue($bs1->is_checksum_correct($checksum)); 00347 } 00348 00349 /* 00350 * test course_backup_setting class 00351 */ 00352 function test_course_backup_setting() { 00353 $bs = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null); 00354 $this->assertEqual($bs->get_level(), backup_setting::COURSE_LEVEL); 00355 00356 // Check checksum implementation is working 00357 $bs1 = new mock_course_backup_setting('test', base_setting::IS_INTEGER, null); 00358 $bs1->set_value(123); 00359 $checksum = $bs1->calculate_checksum(); 00360 $this->assertTrue($checksum); 00361 $this->assertTrue($bs1->is_checksum_correct($checksum)); 00362 } 00363 } 00364 00365 /* 00366 * helper extended base_setting class that makes some methods public for testing 00367 */ 00368 class mock_base_setting extends base_setting { 00369 public function get_vtype() { 00370 return $this->vtype; 00371 } 00372 00373 public function process_change($setting, $ctype, $oldv) { 00374 // Simply, inherit from the main object 00375 $this->set_value($setting->get_value()); 00376 $this->set_visibility($setting->get_visibility()); 00377 $this->set_status($setting->get_status()); 00378 } 00379 00380 public function get_ui_info() { 00381 // Return an array with all the ui info to be tested 00382 return array($this->ui_type, $this->ui_label, $this->ui_values, $this->ui_options); 00383 } 00384 } 00385 00386 /* 00387 * helper extended backup_setting class that makes some methods public for testing 00388 */ 00389 class mock_backup_setting extends backup_setting { 00390 public function set_level($level) { 00391 $this->level = $level; 00392 } 00393 00394 public function process_change($setting, $ctype, $oldv) { 00395 // Simply, inherit from the main object 00396 $this->set_value($setting->get_value()); 00397 $this->set_visibility($setting->get_visibility()); 00398 $this->set_status($setting->get_status()); 00399 } 00400 } 00401 00402 /* 00403 * helper extended activity_backup_setting class that makes some methods public for testing 00404 */ 00405 class mock_activity_backup_setting extends activity_backup_setting { 00406 public function process_change($setting, $ctype, $oldv) { 00407 // Do nothing 00408 } 00409 } 00410 00411 /* 00412 * helper extended section_backup_setting class that makes some methods public for testing 00413 */ 00414 class mock_section_backup_setting extends section_backup_setting { 00415 public function process_change($setting, $ctype, $oldv) { 00416 // Do nothing 00417 } 00418 } 00419 00420 /* 00421 * helper extended course_backup_setting class that makes some methods public for testing 00422 */ 00423 class mock_course_backup_setting extends course_backup_setting { 00424 public function process_change($setting, $ctype, $oldv) { 00425 // Do nothing 00426 } 00427 } 00428 00445 function backup_setting_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { 00446 if ($errno !== E_RECOVERABLE_ERROR) { 00447 // Currently we only want to deal with type hinting errors 00448 return false; 00449 } 00450 throw new backup_setting_exception('incorrect_object_passed'); 00451 }