See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 * Provides the unit tests class and some helper classes 19 * 20 * @package core_plugin 21 * @category test 22 * @copyright 2013, 2015 David Mudrak <david@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once (__DIR__.'/fixtures/testable_update_validator.php'); 29 30 /** 31 * Unit tests for the {@link \core\update\validator} class 32 * 33 * @copyright 2013, 2015 David Mudrak <david@moodle.com> 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class core_update_validator_testcase extends advanced_testcase { 37 38 public function test_validate_files_layout() { 39 $fixtures = __DIR__.'/fixtures/update_validator'; 40 41 // Non-existing directory. 42 $validator = testable_core_update_validator::instance($fixtures.'/nulldir', array( 43 'null/' => true, 44 'null/lang/' => true, 45 'null/lang/en/' => true, 46 'null/lang/en/null.php' => true)); 47 $this->assertEquals('testable_core_update_validator', get_class($validator)); 48 $this->assertFalse($validator->execute()); 49 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 50 'filenotexists', array('file' => 'null/'))); 51 52 // Missing expected file. 53 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 54 'foobar/' => true, 55 'foobar/version.php' => true, 56 'foobar/index.php' => true, 57 'foobar/lang/' => true, 58 'foobar/lang/en/' => true, 59 'foobar/lang/en/local_foobar.php' => true, 60 'foobar/NOTEXISTS.txt' => true)); 61 $this->assertFalse($validator->execute()); 62 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 63 'filenotexists', array('file' => 'foobar/NOTEXISTS.txt'))); 64 65 // Errors during ZIP extraction. 66 $validator = testable_core_update_validator::instance($fixtures.'/multidir', array( 67 'one/' => true, 68 'one/version.php' => 'Can not write target file', 69 'two/' => true, 70 'two/README.txt' => true)); 71 $this->assertFalse($validator->execute()); 72 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'filestatus', 73 array('file' => 'one/version.php', 'status' => 'Can not write target file'))); 74 75 // Insufficient number of extracted files. 76 $validator = testable_core_update_validator::instance($fixtures.'/emptydir', array( 77 'emptydir/' => true, 78 'emptydir/README.txt' => true)); 79 $this->assertFalse($validator->execute()); 80 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'filesnumber')); 81 82 // No wrapping directory. 83 $validator = testable_core_update_validator::instance($fixtures.'/nowrapdir', array( 84 'version.php' => true, 85 'index.php' => true, 86 'lang/' => true, 87 'lang/en/' => true, 88 'lang/en/foo.php' => true)); 89 $this->assertFalse($validator->execute()); 90 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'onedir')); 91 92 // Multiple directories. 93 $validator = testable_core_update_validator::instance($fixtures.'/multidir', array( 94 'one/' => true, 95 'one/version.php' => true, 96 'two/' => true, 97 'two/README.txt' => true)); 98 $this->assertFalse($validator->execute()); 99 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'onedir')); 100 101 // Invalid root directory name. 102 $validator = testable_core_update_validator::instance($fixtures.'/github', array( 103 'moodle-repository_mahara-master/' => true, 104 'moodle-repository_mahara-master/lang/' => true, 105 'moodle-repository_mahara-master/lang/en/' => true, 106 'moodle-repository_mahara-master/lang/en/repository_mahara.php' => true, 107 'moodle-repository_mahara-master/version.php' => true)); 108 $this->assertFalse($validator->execute()); 109 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'rootdirinvalid', 110 'moodle-repository_mahara-master')); 111 } 112 113 public function test_validate_version_php() { 114 $fixtures = __DIR__.'/fixtures/update_validator'; 115 116 $validator = testable_core_update_validator::instance($fixtures.'/noversiontheme', array( 117 'noversion/' => true, 118 'noversion/lang/' => true, 119 'noversion/lang/en/' => true, 120 'noversion/lang/en/theme_noversion.php' => true)); 121 $validator->assert_plugin_type('theme'); 122 $validator->assert_moodle_version(0); 123 $this->assertTrue($validator->execute()); 124 $this->assertTrue($this->has_message($validator->get_messages(), $validator::DEBUG, 'missingversionphp')); 125 $this->assertTrue(is_null($validator->get_versionphp_info())); 126 127 $validator = testable_core_update_validator::instance($fixtures.'/noversionmod', array( 128 'noversion/' => true, 129 'noversion/lang/' => true, 130 'noversion/lang/en/' => true, 131 'noversion/lang/en/noversion.php' => true)); 132 $validator->assert_plugin_type('mod'); 133 $validator->assert_moodle_version(0); 134 $this->assertFalse($validator->execute()); 135 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'missingversionphp')); 136 137 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 138 'legacymod/' => true, 139 'legacymod/version.php' => true, 140 'legacymod/lang/' => true, 141 'legacymod/lang/en/' => true, 142 'legacymod/lang/en/legacymod.php' => true)); 143 $validator->assert_plugin_type('mod'); 144 $validator->assert_moodle_version(0); 145 $this->assertFalse($validator->execute()); 146 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'versionphpsyntax', '$module')); 147 148 $validator = testable_core_update_validator::instance($fixtures.'/nocomponent', array( 149 'baz/' => true, 150 'baz/version.php' => true, 151 'baz/lang/' => true, 152 'baz/lang/en/' => true, 153 'baz/lang/en/auth_baz.php' => true)); 154 $validator->assert_plugin_type('auth'); 155 $validator->assert_moodle_version(0); 156 $this->assertFalse($validator->execute()); 157 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'missingcomponent')); 158 159 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 160 'foobar/' => true, 161 'foobar/version.php' => true, 162 'foobar/index.php' => true, 163 'foobar/lang/' => true)); 164 $validator->assert_plugin_type('block'); 165 $validator->assert_moodle_version('2013031400.00'); 166 $this->assertFalse($validator->execute()); 167 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'componentmismatchtype', 168 array('expected' => 'block', 'found' => 'local'))); 169 170 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 171 'foobar/' => true, 172 'foobar/version.php' => true, 173 'foobar/index.php' => true, 174 'foobar/lang/' => true, 175 'foobar/lang/en/' => true, 176 'foobar/lang/en/local_foobar.php' => true)); 177 $validator->assert_plugin_type('local'); 178 $validator->assert_moodle_version('2013031400.00'); 179 $this->assertTrue($validator->execute()); 180 $this->assertTrue($validator->get_result()); 181 $this->assertEquals('foobar', $validator->get_rootdir()); 182 $this->assertTrue($this->has_message($validator->get_messages(), $validator::INFO, 'rootdir', 'foobar')); 183 $versionphpinfo = $validator->get_versionphp_info(); 184 $this->assertInternalType('array', $versionphpinfo); 185 $this->assertCount(4, $versionphpinfo); 186 $this->assertEquals(2013031900, $versionphpinfo['version']); 187 $this->assertEquals(2013031200, $versionphpinfo['requires']); 188 $this->assertEquals('local_foobar', $versionphpinfo['component']); 189 $this->assertEquals('MATURITY_ALPHA', $versionphpinfo['maturity']); // Note we get the constant name here. 190 $this->assertEquals(MATURITY_ALPHA, constant($versionphpinfo['maturity'])); // This is how to get the real value. 191 $this->assertTrue($this->has_message($validator->get_messages(), $validator::WARNING, 'maturity', 'MATURITY_ALPHA')); 192 } 193 194 public function test_validate_language_pack() { 195 $fixtures = __DIR__.'/fixtures/update_validator'; 196 197 $validator = testable_core_update_validator::instance($fixtures.'/nolang', array( 198 'bah/' => true, 199 'bah/index.php' => true, 200 'bah/view.php' => true, 201 'bah/version.php' => true)); 202 $validator->assert_plugin_type('mod'); 203 $validator->assert_moodle_version(0); 204 $this->assertFalse($validator->execute()); 205 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'missinglangenfolder')); 206 207 $validator = testable_core_update_validator::instance($fixtures.'/nolang', array( 208 'bah/' => true, 209 'bah/version.php' => true, 210 'bah/lang/' => true, 211 'bah/lang/en/' => true)); 212 $validator->assert_plugin_type('mod'); 213 $validator->assert_moodle_version(0); 214 $this->assertFalse($validator->execute()); 215 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'missinglangenfile')); 216 217 $validator = testable_core_update_validator::instance($fixtures.'/nolang', array( 218 'bah/' => true, 219 'bah/version.php' => true, 220 'bah/lang/' => true, 221 'bah/lang/en/' => true, 222 'bah/lang/en/bleh.php' => true, 223 'bah/lang/en/bah.php' => true)); 224 $validator->assert_plugin_type('mod'); 225 $validator->assert_moodle_version(0); 226 $this->assertTrue($validator->execute()); 227 $this->assertTrue($this->has_message($validator->get_messages(), $validator::WARNING, 'multiplelangenfiles')); 228 $this->assertTrue(is_null($validator->get_language_file_name())); 229 230 $validator = testable_core_update_validator::instance($fixtures.'/wronglang', array( 231 'bah/' => true, 232 'bah/version.php' => true, 233 'bah/lang/' => true, 234 'bah/lang/en/' => true, 235 'bah/lang/en/bah.php' => true)); 236 $validator->assert_plugin_type('block'); 237 $validator->assert_moodle_version(0); 238 $this->assertFalse($validator->execute()); 239 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'missingexpectedlangenfile', 240 'block_bah.php')); 241 $this->assertEquals('bah', $validator->get_language_file_name()); 242 243 $validator = testable_core_update_validator::instance($fixtures.'/noversiontheme', array( 244 'noversion/' => true, 245 'noversion/lang/' => true, 246 'noversion/lang/en/' => true, 247 'noversion/lang/en/theme_noversion.php' => true)); 248 $validator->assert_plugin_type('theme'); 249 $validator->assert_moodle_version(0); 250 $this->assertTrue($validator->execute()); 251 $this->assertTrue($this->has_message($validator->get_messages(), $validator::DEBUG, 'foundlangfile', 'theme_noversion')); 252 $this->assertEquals('theme_noversion', $validator->get_language_file_name()); 253 254 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 255 'foobar/' => true, 256 'foobar/version.php' => true, 257 'foobar/index.php' => true, 258 'foobar/lang/' => true, 259 'foobar/lang/en/' => true, 260 'foobar/lang/en/local_foobar.php' => true)); 261 $validator->assert_plugin_type('local'); 262 $validator->assert_moodle_version('2013031400.00'); 263 $this->assertTrue($validator->execute()); 264 $this->assertTrue($this->has_message($validator->get_messages(), $validator::DEBUG, 'foundlangfile', 'local_foobar')); 265 $this->assertEquals('local_foobar', $validator->get_language_file_name()); 266 } 267 268 public function test_validate_target_location() { 269 $fixtures = __DIR__.'/fixtures/update_validator'; 270 271 $validator = testable_core_update_validator::instance($fixtures.'/installed', array( 272 'greenbar/' => true, 273 'greenbar/version.php' => true, 274 'greenbar/index.php' => true, 275 'greenbar/lang/' => true, 276 'greenbar/lang/en/' => true, 277 'greenbar/lang/en/local_greenbar.php' => true)); 278 $validator->assert_plugin_type('local'); 279 $validator->assert_moodle_version('2013031400.00'); 280 281 $this->assertTrue($validator->execute()); 282 $this->assertFalse($this->has_message($validator->get_messages(), $validator::WARNING, 'targetexists', 283 $validator->get_plugintype_location('local').'/greenbar')); 284 285 $typeroot = $validator->get_plugintype_location('local'); 286 make_writable_directory($typeroot.'/greenbar'); 287 $this->assertTrue($validator->execute()); 288 $this->assertTrue($this->has_message($validator->get_messages(), $validator::WARNING, 'targetexists', 289 $validator->get_plugintype_location('local').'/greenbar')); 290 291 remove_dir($typeroot.'/greenbar'); 292 file_put_contents($typeroot.'/greenbar', 'This file occupies a place where a plugin should land.'); 293 $this->assertFalse($validator->execute()); 294 $this->assertTrue($this->has_message($validator->get_messages(), $validator::ERROR, 'targetnotdir', 295 $validator->get_plugintype_location('local').'/greenbar')); 296 297 unlink($typeroot.'/greenbar'); 298 $this->assertTrue($validator->execute()); 299 300 $validator = testable_core_update_validator::instance($fixtures.'/plugindir', array( 301 'foobar/' => true, 302 'foobar/version.php' => true, 303 'foobar/index.php' => true, 304 'foobar/lang/' => true, 305 'foobar/lang/en/' => true, 306 'foobar/lang/en/local_foobar.php' => true)); 307 $validator->assert_plugin_type('local'); 308 $validator->assert_moodle_version('2013031400.00'); 309 $this->assertTrue($validator->execute()); 310 $this->assertTrue($this->has_message($validator->get_messages(), $validator::INFO, 'pathwritable', 311 $validator->get_plugintype_location('local'))); 312 } 313 314 public function test_parse_version_php() { 315 $fixtures = __DIR__.'/fixtures/update_validator/versionphp'; 316 317 $validator = testable_core_update_validator::instance($fixtures, array()); 318 $this->assertEquals('testable_core_update_validator', get_class($validator)); 319 320 $info = $validator->testable_parse_version_php($fixtures.'/version1.php'); 321 $this->assertInternalType('array', $info); 322 $this->assertCount(7, $info); 323 $this->assertEquals('block_foobar', $info['plugin->component']); // Later in the file. 324 $this->assertEquals('2013010100', $info['plugin->version']); // Numeric wins over strings. 325 $this->assertEquals('2012122401', $info['plugin->requires']); // Commented. 326 $this->assertEquals('MATURITY_STABLE', $info['module->maturity']);// Constant wins regardless the order (non-PHP behaviour). 327 $this->assertEquals('MATURITY_ALPHA', $info['plugin->maturity']); // Constant wins regardless the order (non-PHP behaviour). 328 $this->assertEquals('v2.3', $info['module->release']); // String wins over numeric (non-PHP behaviour). 329 $this->assertEquals('v2.4', $info['plugin->release']); // String wins over numeric (non-PHP behaviour). 330 } 331 332 public function test_messages_output() { 333 $fixtures = __DIR__.'/fixtures/update_validator'; 334 $validator = testable_core_update_validator::instance($fixtures, array()); 335 336 $this->assertDebuggingNotCalled(); 337 $this->assertNotEmpty($validator->message_level_name($validator::ERROR)); 338 $this->assertNotEmpty($validator->message_level_name($validator::WARNING)); 339 $this->assertNotEmpty($validator->message_level_name($validator::INFO)); 340 $this->assertNotEmpty($validator->message_level_name($validator::DEBUG)); 341 342 $this->assertNotEmpty($validator->message_code_name('missingversion')); 343 $this->assertSame( 344 'some_really_crazy_message_code_that_is_not_localised', 345 $validator->message_code_name('some_really_crazy_message_code_that_is_not_localised') 346 ); 347 348 $this->assertInstanceOf('help_icon', $validator->message_help_icon('onedir')); 349 $this->assertFalse($validator->message_help_icon('some_really_crazy_message_code_that_is_not_localised')); 350 351 $this->assertNotEmpty($validator->message_code_info('missingexpectedlangenfile', 'something')); 352 $this->assertSame('', $validator->message_code_info('missingexpectedlangenfile', null)); 353 $this->assertSame('', $validator->message_code_info('some_really_crazy_message_code_that_is_not_localised', 'something')); 354 } 355 356 /** 357 * Helper method for checking if the given message has been raised by the validator. 358 * 359 * @param array $messages list of returned messages 360 * @param string $level expected message severity level 361 * @param string $msgcode expected message code 362 * @param string|array $addinfo expected additional info 363 * @return bool 364 */ 365 protected function has_message(array $messages, $level, $msgcode, $addinfo = null) { 366 foreach ($messages as $message) { 367 if ($message->level === $level and $message->msgcode === $msgcode and $message->addinfo === $addinfo) { 368 return true; 369 } 370 } 371 return false; 372 } 373 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body