PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/tests/moodlelib_test.php

https://bitbucket.org/jvomarques/moodle-esmarn
PHP | 3595 lines | 2660 code | 434 blank | 501 comment | 7 complexity | d91c03a3b7226a94a8e7b9f5542dd5a1 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, BSD-3-Clause, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  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. * Unit tests for (some of) ../moodlelib.php.
  18. *
  19. * @package core
  20. * @category phpunit
  21. * @copyright &copy; 2006 The Open University
  22. * @author T.J.Hunt@open.ac.uk
  23. * @author nicolas@moodle.com
  24. */
  25. defined('MOODLE_INTERNAL') || die();
  26. class core_moodlelib_testcase extends advanced_testcase {
  27. public static $includecoverage = array('lib/moodlelib.php');
  28. /**
  29. * Define a local decimal separator.
  30. *
  31. * It is not possible to directly change the result of get_string in
  32. * a unit test. Instead, we create a language pack for language 'xx' in
  33. * dataroot and make langconfig.php with the string we need to change.
  34. * The example separator used here is 'X'; on PHP 5.3 and before this
  35. * must be a single byte character due to PHP bug/limitation in
  36. * number_format, so you can't use UTF-8 characters.
  37. */
  38. protected function define_local_decimal_separator() {
  39. global $SESSION, $CFG;
  40. $SESSION->lang = 'xx';
  41. $langconfig = "<?php\n\$string['decsep'] = 'X';";
  42. $langfolder = $CFG->dataroot . '/lang/xx';
  43. check_dir_exists($langfolder);
  44. file_put_contents($langfolder . '/langconfig.php', $langconfig);
  45. }
  46. public function test_cleanremoteaddr() {
  47. // IPv4.
  48. $this->assertNull(cleanremoteaddr('1023.121.234.1'));
  49. $this->assertSame('123.121.234.1', cleanremoteaddr('123.121.234.01 '));
  50. // IPv6.
  51. $this->assertNull(cleanremoteaddr('0:0:0:0:0:0:0:0:0'));
  52. $this->assertNull(cleanremoteaddr('0:0:0:0:0:0:0:abh'));
  53. $this->assertNull(cleanremoteaddr('0:0:0:::0:0:1'));
  54. $this->assertSame('::', cleanremoteaddr('0:0:0:0:0:0:0:0', true));
  55. $this->assertSame('::1:1', cleanremoteaddr('0:0:0:0:0:0:1:1', true));
  56. $this->assertSame('abcd:ef::', cleanremoteaddr('abcd:00ef:0:0:0:0:0:0', true));
  57. $this->assertSame('1::1', cleanremoteaddr('1:0:0:0:0:0:0:1', true));
  58. $this->assertSame('0:0:0:0:0:0:10:1', cleanremoteaddr('::10:1', false));
  59. $this->assertSame('1:1:0:0:0:0:0:0', cleanremoteaddr('01:1::', false));
  60. $this->assertSame('10:0:0:0:0:0:0:10', cleanremoteaddr('10::10', false));
  61. $this->assertSame('::ffff:c0a8:11', cleanremoteaddr('::ffff:192.168.1.1', true));
  62. }
  63. public function test_address_in_subnet() {
  64. // 1: xxx.xxx.xxx.xxx/nn or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/nnn (number of bits in net mask).
  65. $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.1/32'));
  66. $this->assertFalse(address_in_subnet('123.121.23.1', '123.121.23.0/32'));
  67. $this->assertTrue(address_in_subnet('10.10.10.100', '123.121.23.45/0'));
  68. $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.0/24'));
  69. $this->assertFalse(address_in_subnet('123.121.34.1', '123.121.234.0/24'));
  70. $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.0/30'));
  71. $this->assertFalse(address_in_subnet('123.121.23.8', '123.121.23.0/30'));
  72. $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba/128'));
  73. $this->assertFalse(address_in_subnet('bab:baba::baba', 'bab:baba::cece/128'));
  74. $this->assertTrue(address_in_subnet('baba:baba::baba', 'cece:cece::cece/0'));
  75. $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba/128'));
  76. $this->assertTrue(address_in_subnet('baba:baba::00ba', 'baba:baba::/120'));
  77. $this->assertFalse(address_in_subnet('baba:baba::aba', 'baba:baba::/120'));
  78. $this->assertTrue(address_in_subnet('baba::baba:00ba', 'baba::baba:0/112'));
  79. $this->assertFalse(address_in_subnet('baba::aba:00ba', 'baba::baba:0/112'));
  80. $this->assertFalse(address_in_subnet('aba::baba:0000', 'baba::baba:0/112'));
  81. // Fixed input.
  82. $this->assertTrue(address_in_subnet('123.121.23.1 ', ' 123.121.23.0 / 24'));
  83. $this->assertTrue(address_in_subnet('::ffff:10.1.1.1', ' 0:0:0:000:0:ffff:a1:10 / 126'));
  84. // Incorrect input.
  85. $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/-2'));
  86. $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/64'));
  87. $this->assertFalse(address_in_subnet('123.121.234.x', '123.121.234.1/24'));
  88. $this->assertFalse(address_in_subnet('123.121.234.0', '123.121.234.xx/24'));
  89. $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/xx0'));
  90. $this->assertFalse(address_in_subnet('::1', '::aa:0/xx0'));
  91. $this->assertFalse(address_in_subnet('::1', '::aa:0/-5'));
  92. $this->assertFalse(address_in_subnet('::1', '::aa:0/130'));
  93. $this->assertFalse(address_in_subnet('x:1', '::aa:0/130'));
  94. $this->assertFalse(address_in_subnet('::1', '::ax:0/130'));
  95. // 2: xxx.xxx.xxx.xxx-yyy or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::xxxx-yyyy (a range of IP addresses in the last group).
  96. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12-14'));
  97. $this->assertTrue(address_in_subnet('123.121.234.13', '123.121.234.12-14'));
  98. $this->assertTrue(address_in_subnet('123.121.234.14', '123.121.234.12-14'));
  99. $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.12-14'));
  100. $this->assertFalse(address_in_subnet('123.121.234.20', '123.121.234.12-14'));
  101. $this->assertFalse(address_in_subnet('123.121.23.12', '123.121.234.12-14'));
  102. $this->assertFalse(address_in_subnet('123.12.234.12', '123.121.234.12-14'));
  103. $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba-babe'));
  104. $this->assertTrue(address_in_subnet('baba:baba::babc', 'baba:baba::baba-babe'));
  105. $this->assertTrue(address_in_subnet('baba:baba::babe', 'baba:baba::baba-babe'));
  106. $this->assertFalse(address_in_subnet('bab:baba::bab0', 'bab:baba::baba-babe'));
  107. $this->assertFalse(address_in_subnet('bab:baba::babf', 'bab:baba::baba-babe'));
  108. $this->assertFalse(address_in_subnet('bab:baba::bfbe', 'bab:baba::baba-babe'));
  109. $this->assertFalse(address_in_subnet('bfb:baba::babe', 'bab:baba::baba-babe'));
  110. // Fixed input.
  111. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12 - 14 '));
  112. $this->assertTrue(address_in_subnet('bab:baba::babe', 'bab:baba::baba - babe '));
  113. // Incorrect input.
  114. $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12-234.14'));
  115. $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12-256'));
  116. $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12--256'));
  117. // 3: xxx.xxx or xxx.xxx. or xxx:xxx:xxxx or xxx:xxx:xxxx. (incomplete address, a bit non-technical ;-).
  118. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12'));
  119. $this->assertFalse(address_in_subnet('123.121.23.12', '123.121.23.13'));
  120. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.'));
  121. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234'));
  122. $this->assertTrue(address_in_subnet('123.121.234.12', '123.121'));
  123. $this->assertTrue(address_in_subnet('123.121.234.12', '123'));
  124. $this->assertFalse(address_in_subnet('123.121.234.1', '12.121.234.'));
  125. $this->assertFalse(address_in_subnet('123.121.234.1', '12.121.234'));
  126. $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:baba::bab'));
  127. $this->assertFalse(address_in_subnet('baba:baba::ba', 'baba:baba::bc'));
  128. $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:baba'));
  129. $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:'));
  130. $this->assertFalse(address_in_subnet('bab:baba::bab', 'baba:'));
  131. // Multiple subnets.
  132. $this->assertTrue(address_in_subnet('123.121.234.12', '::1/64, 124., 123.121.234.10-30'));
  133. $this->assertTrue(address_in_subnet('124.121.234.12', '::1/64, 124., 123.121.234.10-30'));
  134. $this->assertTrue(address_in_subnet('::2', '::1/64, 124., 123.121.234.10-30'));
  135. $this->assertFalse(address_in_subnet('12.121.234.12', '::1/64, 124., 123.121.234.10-30'));
  136. // Other incorrect input.
  137. $this->assertFalse(address_in_subnet('123.123.123.123', ''));
  138. }
  139. public function test_fix_utf8() {
  140. // Make sure valid data including other types is not changed.
  141. $this->assertSame(null, fix_utf8(null));
  142. $this->assertSame(1, fix_utf8(1));
  143. $this->assertSame(1.1, fix_utf8(1.1));
  144. $this->assertSame(true, fix_utf8(true));
  145. $this->assertSame('', fix_utf8(''));
  146. $this->assertSame('abc', fix_utf8('abc'));
  147. $array = array('do', 're', 'mi');
  148. $this->assertSame($array, fix_utf8($array));
  149. $object = new stdClass();
  150. $object->a = 'aa';
  151. $object->b = 'bb';
  152. $this->assertEquals($object, fix_utf8($object));
  153. // valid utf8 string
  154. $this->assertSame("žlutý koníček přeskočil potůček \n\t\r", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
  155. // Invalid utf8 string.
  156. $this->assertSame('aš', fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
  157. }
  158. public function test_optional_param() {
  159. global $CFG;
  160. $_POST['username'] = 'post_user';
  161. $_GET['username'] = 'get_user';
  162. $this->assertSame($_POST['username'], optional_param('username', 'default_user', PARAM_RAW));
  163. unset($_POST['username']);
  164. $this->assertSame($_GET['username'], optional_param('username', 'default_user', PARAM_RAW));
  165. unset($_GET['username']);
  166. $this->assertSame('default_user', optional_param('username', 'default_user', PARAM_RAW));
  167. // Make sure exception is triggered when some params are missing, hide error notices here - new in 2.2.
  168. $_POST['username'] = 'post_user';
  169. try {
  170. optional_param('username', 'default_user', null);
  171. $this->fail('coding_exception expected');
  172. } catch (moodle_exception $ex) {
  173. $this->assertInstanceOf('coding_exception', $ex);
  174. }
  175. try {
  176. @optional_param('username', 'default_user');
  177. $this->fail('coding_exception expected');
  178. } catch (moodle_exception $ex) {
  179. $this->assertInstanceOf('coding_exception', $ex);
  180. } catch (Error $error) {
  181. // PHP 7.1 throws Error even earlier.
  182. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  183. }
  184. try {
  185. @optional_param('username');
  186. $this->fail('coding_exception expected');
  187. } catch (moodle_exception $ex) {
  188. $this->assertInstanceOf('coding_exception', $ex);
  189. } catch (Error $error) {
  190. // PHP 7.1 throws Error even earlier.
  191. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  192. }
  193. try {
  194. optional_param('', 'default_user', PARAM_RAW);
  195. $this->fail('coding_exception expected');
  196. } catch (moodle_exception $ex) {
  197. $this->assertInstanceOf('coding_exception', $ex);
  198. }
  199. // Make sure warning is displayed if array submitted - TODO: throw exception in Moodle 2.3.
  200. $_POST['username'] = array('a'=>'a');
  201. $this->assertSame($_POST['username'], optional_param('username', 'default_user', PARAM_RAW));
  202. $this->assertDebuggingCalled();
  203. }
  204. public function test_optional_param_array() {
  205. global $CFG;
  206. $_POST['username'] = array('a'=>'post_user');
  207. $_GET['username'] = array('a'=>'get_user');
  208. $this->assertSame($_POST['username'], optional_param_array('username', array('a'=>'default_user'), PARAM_RAW));
  209. unset($_POST['username']);
  210. $this->assertSame($_GET['username'], optional_param_array('username', array('a'=>'default_user'), PARAM_RAW));
  211. unset($_GET['username']);
  212. $this->assertSame(array('a'=>'default_user'), optional_param_array('username', array('a'=>'default_user'), PARAM_RAW));
  213. // Make sure exception is triggered when some params are missing, hide error notices here - new in 2.2.
  214. $_POST['username'] = array('a'=>'post_user');
  215. try {
  216. optional_param_array('username', array('a'=>'default_user'), null);
  217. $this->fail('coding_exception expected');
  218. } catch (moodle_exception $ex) {
  219. $this->assertInstanceOf('coding_exception', $ex);
  220. }
  221. try {
  222. @optional_param_array('username', array('a'=>'default_user'));
  223. $this->fail('coding_exception expected');
  224. } catch (moodle_exception $ex) {
  225. $this->assertInstanceOf('coding_exception', $ex);
  226. } catch (Error $error) {
  227. // PHP 7.1 throws Error even earlier.
  228. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  229. }
  230. try {
  231. @optional_param_array('username');
  232. $this->fail('coding_exception expected');
  233. } catch (moodle_exception $ex) {
  234. $this->assertInstanceOf('coding_exception', $ex);
  235. } catch (Error $error) {
  236. // PHP 7.1 throws Error even earlier.
  237. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  238. }
  239. try {
  240. optional_param_array('', array('a'=>'default_user'), PARAM_RAW);
  241. $this->fail('coding_exception expected');
  242. } catch (moodle_exception $ex) {
  243. $this->assertInstanceOf('coding_exception', $ex);
  244. }
  245. // Do not allow nested arrays.
  246. try {
  247. $_POST['username'] = array('a'=>array('b'=>'post_user'));
  248. optional_param_array('username', array('a'=>'default_user'), PARAM_RAW);
  249. $this->fail('coding_exception expected');
  250. } catch (coding_exception $ex) {
  251. $this->assertTrue(true);
  252. }
  253. // Do not allow non-arrays.
  254. $_POST['username'] = 'post_user';
  255. $this->assertSame(array('a'=>'default_user'), optional_param_array('username', array('a'=>'default_user'), PARAM_RAW));
  256. $this->assertDebuggingCalled();
  257. // Make sure array keys are sanitised.
  258. $_POST['username'] = array('abc123_;-/*-+ '=>'arrggh', 'a1_-'=>'post_user');
  259. $this->assertSame(array('a1_-'=>'post_user'), optional_param_array('username', array(), PARAM_RAW));
  260. $this->assertDebuggingCalled();
  261. }
  262. public function test_required_param() {
  263. $_POST['username'] = 'post_user';
  264. $_GET['username'] = 'get_user';
  265. $this->assertSame('post_user', required_param('username', PARAM_RAW));
  266. unset($_POST['username']);
  267. $this->assertSame('get_user', required_param('username', PARAM_RAW));
  268. unset($_GET['username']);
  269. try {
  270. $this->assertSame('default_user', required_param('username', PARAM_RAW));
  271. $this->fail('moodle_exception expected');
  272. } catch (moodle_exception $ex) {
  273. $this->assertInstanceOf('moodle_exception', $ex);
  274. }
  275. // Make sure exception is triggered when some params are missing, hide error notices here - new in 2.2.
  276. $_POST['username'] = 'post_user';
  277. try {
  278. @required_param('username');
  279. $this->fail('coding_exception expected');
  280. } catch (moodle_exception $ex) {
  281. $this->assertInstanceOf('coding_exception', $ex);
  282. } catch (Error $error) {
  283. // PHP 7.1 throws Error even earlier.
  284. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  285. }
  286. try {
  287. required_param('username', '');
  288. $this->fail('coding_exception expected');
  289. } catch (moodle_exception $ex) {
  290. $this->assertInstanceOf('coding_exception', $ex);
  291. }
  292. try {
  293. required_param('', PARAM_RAW);
  294. $this->fail('coding_exception expected');
  295. } catch (moodle_exception $ex) {
  296. $this->assertInstanceOf('coding_exception', $ex);
  297. }
  298. // Make sure warning is displayed if array submitted - TODO: throw exception in Moodle 2.3.
  299. $_POST['username'] = array('a'=>'a');
  300. $this->assertSame($_POST['username'], required_param('username', PARAM_RAW));
  301. $this->assertDebuggingCalled();
  302. }
  303. public function test_required_param_array() {
  304. global $CFG;
  305. $_POST['username'] = array('a'=>'post_user');
  306. $_GET['username'] = array('a'=>'get_user');
  307. $this->assertSame($_POST['username'], required_param_array('username', PARAM_RAW));
  308. unset($_POST['username']);
  309. $this->assertSame($_GET['username'], required_param_array('username', PARAM_RAW));
  310. // Make sure exception is triggered when some params are missing, hide error notices here - new in 2.2.
  311. $_POST['username'] = array('a'=>'post_user');
  312. try {
  313. required_param_array('username', null);
  314. $this->fail('coding_exception expected');
  315. } catch (moodle_exception $ex) {
  316. $this->assertInstanceOf('coding_exception', $ex);
  317. }
  318. try {
  319. @required_param_array('username');
  320. $this->fail('coding_exception expected');
  321. } catch (moodle_exception $ex) {
  322. $this->assertInstanceOf('coding_exception', $ex);
  323. } catch (Error $error) {
  324. // PHP 7.1 throws Error.
  325. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  326. }
  327. try {
  328. required_param_array('', PARAM_RAW);
  329. $this->fail('coding_exception expected');
  330. } catch (moodle_exception $ex) {
  331. $this->assertInstanceOf('coding_exception', $ex);
  332. }
  333. // Do not allow nested arrays.
  334. try {
  335. $_POST['username'] = array('a'=>array('b'=>'post_user'));
  336. required_param_array('username', PARAM_RAW);
  337. $this->fail('coding_exception expected');
  338. } catch (moodle_exception $ex) {
  339. $this->assertInstanceOf('coding_exception', $ex);
  340. }
  341. // Do not allow non-arrays.
  342. try {
  343. $_POST['username'] = 'post_user';
  344. required_param_array('username', PARAM_RAW);
  345. $this->fail('moodle_exception expected');
  346. } catch (moodle_exception $ex) {
  347. $this->assertInstanceOf('moodle_exception', $ex);
  348. }
  349. // Make sure array keys are sanitised.
  350. $_POST['username'] = array('abc123_;-/*-+ '=>'arrggh', 'a1_-'=>'post_user');
  351. $this->assertSame(array('a1_-'=>'post_user'), required_param_array('username', PARAM_RAW));
  352. $this->assertDebuggingCalled();
  353. }
  354. public function test_clean_param() {
  355. // Forbid objects and arrays.
  356. try {
  357. clean_param(array('x', 'y'), PARAM_RAW);
  358. $this->fail('coding_exception expected');
  359. } catch (moodle_exception $ex) {
  360. $this->assertInstanceOf('coding_exception', $ex);
  361. }
  362. try {
  363. $param = new stdClass();
  364. $param->id = 1;
  365. clean_param($param, PARAM_RAW);
  366. $this->fail('coding_exception expected');
  367. } catch (moodle_exception $ex) {
  368. $this->assertInstanceOf('coding_exception', $ex);
  369. }
  370. // Require correct type.
  371. try {
  372. clean_param('x', 'xxxxxx');
  373. $this->fail('moodle_exception expected');
  374. } catch (moodle_exception $ex) {
  375. $this->assertInstanceOf('moodle_exception', $ex);
  376. }
  377. try {
  378. @clean_param('x');
  379. $this->fail('moodle_exception expected');
  380. } catch (moodle_exception $ex) {
  381. $this->assertInstanceOf('moodle_exception', $ex);
  382. } catch (Error $error) {
  383. // PHP 7.1 throws Error even earlier.
  384. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  385. }
  386. }
  387. public function test_clean_param_array() {
  388. $this->assertSame(array(), clean_param_array(null, PARAM_RAW));
  389. $this->assertSame(array('a', 'b'), clean_param_array(array('a', 'b'), PARAM_RAW));
  390. $this->assertSame(array('a', array('b')), clean_param_array(array('a', array('b')), PARAM_RAW, true));
  391. // Require correct type.
  392. try {
  393. clean_param_array(array('x'), 'xxxxxx');
  394. $this->fail('moodle_exception expected');
  395. } catch (moodle_exception $ex) {
  396. $this->assertInstanceOf('moodle_exception', $ex);
  397. }
  398. try {
  399. @clean_param_array(array('x'));
  400. $this->fail('moodle_exception expected');
  401. } catch (moodle_exception $ex) {
  402. $this->assertInstanceOf('moodle_exception', $ex);
  403. } catch (Error $error) {
  404. // PHP 7.1 throws Error even earlier.
  405. $this->assertRegExp('/Too few arguments to function/', $error->getMessage());
  406. }
  407. try {
  408. clean_param_array(array('x', array('y')), PARAM_RAW);
  409. $this->fail('coding_exception expected');
  410. } catch (moodle_exception $ex) {
  411. $this->assertInstanceOf('coding_exception', $ex);
  412. }
  413. // Test recursive.
  414. }
  415. public function test_clean_param_raw() {
  416. $this->assertSame(
  417. '#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)',
  418. clean_param('#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)', PARAM_RAW));
  419. }
  420. public function test_clean_param_trim() {
  421. $this->assertSame('Frog toad', clean_param(" Frog toad \r\n ", PARAM_RAW_TRIMMED));
  422. }
  423. public function test_clean_param_clean() {
  424. // PARAM_CLEAN is an ugly hack, do not use in new code (skodak),
  425. // instead use more specific type, or submit sothing that can be verified properly.
  426. $this->assertSame('xx', clean_param('xx<script>', PARAM_CLEAN));
  427. }
  428. public function test_clean_param_alpha() {
  429. $this->assertSame('DSFMOSDJ', clean_param('#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)', PARAM_ALPHA));
  430. }
  431. public function test_clean_param_alphanum() {
  432. $this->assertSame('978942897DSFMOSDJ', clean_param('#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)', PARAM_ALPHANUM));
  433. }
  434. public function test_clean_param_alphaext() {
  435. $this->assertSame('DSFMOSDJ', clean_param('#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)', PARAM_ALPHAEXT));
  436. }
  437. public function test_clean_param_sequence() {
  438. $this->assertSame(',9789,42897', clean_param('#()*#,9789\'".,<42897></?$(*DSFMO#$*)(SDJ)($*)', PARAM_SEQUENCE));
  439. }
  440. public function test_clean_param_component() {
  441. // Please note the cleaning of component names is very strict, no guessing here.
  442. $this->assertSame('mod_forum', clean_param('mod_forum', PARAM_COMPONENT));
  443. $this->assertSame('block_online_users', clean_param('block_online_users', PARAM_COMPONENT));
  444. $this->assertSame('block_blond_online_users', clean_param('block_blond_online_users', PARAM_COMPONENT));
  445. $this->assertSame('mod_something2', clean_param('mod_something2', PARAM_COMPONENT));
  446. $this->assertSame('forum', clean_param('forum', PARAM_COMPONENT));
  447. $this->assertSame('user', clean_param('user', PARAM_COMPONENT));
  448. $this->assertSame('rating', clean_param('rating', PARAM_COMPONENT));
  449. $this->assertSame('feedback360', clean_param('feedback360', PARAM_COMPONENT));
  450. $this->assertSame('mod_feedback360', clean_param('mod_feedback360', PARAM_COMPONENT));
  451. $this->assertSame('', clean_param('mod_2something', PARAM_COMPONENT));
  452. $this->assertSame('', clean_param('2mod_something', PARAM_COMPONENT));
  453. $this->assertSame('', clean_param('mod_something_xx', PARAM_COMPONENT));
  454. $this->assertSame('', clean_param('auth_something__xx', PARAM_COMPONENT));
  455. $this->assertSame('', clean_param('mod_Something', PARAM_COMPONENT));
  456. $this->assertSame('', clean_param('mod_somethíng', PARAM_COMPONENT));
  457. $this->assertSame('', clean_param('mod__something', PARAM_COMPONENT));
  458. $this->assertSame('', clean_param('auth_xx-yy', PARAM_COMPONENT));
  459. $this->assertSame('', clean_param('_auth_xx', PARAM_COMPONENT));
  460. $this->assertSame('', clean_param('a2uth_xx', PARAM_COMPONENT));
  461. $this->assertSame('', clean_param('auth_xx_', PARAM_COMPONENT));
  462. $this->assertSame('', clean_param('auth_xx.old', PARAM_COMPONENT));
  463. $this->assertSame('', clean_param('_user', PARAM_COMPONENT));
  464. $this->assertSame('', clean_param('2rating', PARAM_COMPONENT));
  465. $this->assertSame('', clean_param('user_', PARAM_COMPONENT));
  466. }
  467. public function test_is_valid_plugin_name() {
  468. $this->assertTrue(is_valid_plugin_name('forum'));
  469. $this->assertTrue(is_valid_plugin_name('forum2'));
  470. $this->assertTrue(is_valid_plugin_name('feedback360'));
  471. $this->assertTrue(is_valid_plugin_name('online_users'));
  472. $this->assertTrue(is_valid_plugin_name('blond_online_users'));
  473. $this->assertFalse(is_valid_plugin_name('online__users'));
  474. $this->assertFalse(is_valid_plugin_name('forum '));
  475. $this->assertFalse(is_valid_plugin_name('forum.old'));
  476. $this->assertFalse(is_valid_plugin_name('xx-yy'));
  477. $this->assertFalse(is_valid_plugin_name('2xx'));
  478. $this->assertFalse(is_valid_plugin_name('Xx'));
  479. $this->assertFalse(is_valid_plugin_name('_xx'));
  480. $this->assertFalse(is_valid_plugin_name('xx_'));
  481. }
  482. public function test_clean_param_plugin() {
  483. // Please note the cleaning of plugin names is very strict, no guessing here.
  484. $this->assertSame('forum', clean_param('forum', PARAM_PLUGIN));
  485. $this->assertSame('forum2', clean_param('forum2', PARAM_PLUGIN));
  486. $this->assertSame('feedback360', clean_param('feedback360', PARAM_PLUGIN));
  487. $this->assertSame('online_users', clean_param('online_users', PARAM_PLUGIN));
  488. $this->assertSame('blond_online_users', clean_param('blond_online_users', PARAM_PLUGIN));
  489. $this->assertSame('', clean_param('online__users', PARAM_PLUGIN));
  490. $this->assertSame('', clean_param('forum ', PARAM_PLUGIN));
  491. $this->assertSame('', clean_param('forum.old', PARAM_PLUGIN));
  492. $this->assertSame('', clean_param('xx-yy', PARAM_PLUGIN));
  493. $this->assertSame('', clean_param('2xx', PARAM_PLUGIN));
  494. $this->assertSame('', clean_param('Xx', PARAM_PLUGIN));
  495. $this->assertSame('', clean_param('_xx', PARAM_PLUGIN));
  496. $this->assertSame('', clean_param('xx_', PARAM_PLUGIN));
  497. }
  498. public function test_clean_param_area() {
  499. // Please note the cleaning of area names is very strict, no guessing here.
  500. $this->assertSame('something', clean_param('something', PARAM_AREA));
  501. $this->assertSame('something2', clean_param('something2', PARAM_AREA));
  502. $this->assertSame('some_thing', clean_param('some_thing', PARAM_AREA));
  503. $this->assertSame('some_thing_xx', clean_param('some_thing_xx', PARAM_AREA));
  504. $this->assertSame('feedback360', clean_param('feedback360', PARAM_AREA));
  505. $this->assertSame('', clean_param('_something', PARAM_AREA));
  506. $this->assertSame('', clean_param('something_', PARAM_AREA));
  507. $this->assertSame('', clean_param('2something', PARAM_AREA));
  508. $this->assertSame('', clean_param('Something', PARAM_AREA));
  509. $this->assertSame('', clean_param('some-thing', PARAM_AREA));
  510. $this->assertSame('', clean_param('somethííng', PARAM_AREA));
  511. $this->assertSame('', clean_param('something.x', PARAM_AREA));
  512. }
  513. public function test_clean_param_text() {
  514. $this->assertSame(PARAM_TEXT, PARAM_MULTILANG);
  515. // Standard.
  516. $this->assertSame('xx<lang lang="en">aa</lang><lang lang="yy">pp</lang>', clean_param('xx<lang lang="en">aa</lang><lang lang="yy">pp</lang>', PARAM_TEXT));
  517. $this->assertSame('<span lang="en" class="multilang">aa</span><span lang="xy" class="multilang">bb</span>', clean_param('<span lang="en" class="multilang">aa</span><span lang="xy" class="multilang">bb</span>', PARAM_TEXT));
  518. $this->assertSame('xx<lang lang="en">aa'."\n".'</lang><lang lang="yy">pp</lang>', clean_param('xx<lang lang="en">aa'."\n".'</lang><lang lang="yy">pp</lang>', PARAM_TEXT));
  519. // Malformed.
  520. $this->assertSame('<span lang="en" class="multilang">aa</span>', clean_param('<span lang="en" class="multilang">aa</span>', PARAM_TEXT));
  521. $this->assertSame('aa', clean_param('<span lang="en" class="nothing" class="multilang">aa</span>', PARAM_TEXT));
  522. $this->assertSame('aa', clean_param('<lang lang="en" class="multilang">aa</lang>', PARAM_TEXT));
  523. $this->assertSame('aa', clean_param('<lang lang="en!!">aa</lang>', PARAM_TEXT));
  524. $this->assertSame('aa', clean_param('<span lang="en==" class="multilang">aa</span>', PARAM_TEXT));
  525. $this->assertSame('abc', clean_param('a<em>b</em>c', PARAM_TEXT));
  526. $this->assertSame('a>c>', clean_param('a><xx >c>', PARAM_TEXT)); // Standard strip_tags() behaviour.
  527. $this->assertSame('a', clean_param('a<b', PARAM_TEXT));
  528. $this->assertSame('a>b', clean_param('a>b', PARAM_TEXT));
  529. $this->assertSame('<lang lang="en">a>a</lang>', clean_param('<lang lang="en">a>a</lang>', PARAM_TEXT)); // Standard strip_tags() behaviour.
  530. $this->assertSame('a', clean_param('<lang lang="en">a<a</lang>', PARAM_TEXT));
  531. $this->assertSame('<lang lang="en">aa</lang>', clean_param('<lang lang="en">a<br>a</lang>', PARAM_TEXT));
  532. }
  533. public function test_clean_param_url() {
  534. // Test PARAM_URL and PARAM_LOCALURL a bit.
  535. // Valid URLs.
  536. $this->assertSame('http://google.com/', clean_param('http://google.com/', PARAM_URL));
  537. $this->assertSame('http://some.very.long.and.silly.domain/with/a/path/', clean_param('http://some.very.long.and.silly.domain/with/a/path/', PARAM_URL));
  538. $this->assertSame('http://localhost/', clean_param('http://localhost/', PARAM_URL));
  539. $this->assertSame('http://0.255.1.1/numericip.php', clean_param('http://0.255.1.1/numericip.php', PARAM_URL));
  540. $this->assertSame('https://google.com/', clean_param('https://google.com/', PARAM_URL));
  541. $this->assertSame('https://some.very.long.and.silly.domain/with/a/path/', clean_param('https://some.very.long.and.silly.domain/with/a/path/', PARAM_URL));
  542. $this->assertSame('https://localhost/', clean_param('https://localhost/', PARAM_URL));
  543. $this->assertSame('https://0.255.1.1/numericip.php', clean_param('https://0.255.1.1/numericip.php', PARAM_URL));
  544. $this->assertSame('ftp://ftp.debian.org/debian/', clean_param('ftp://ftp.debian.org/debian/', PARAM_URL));
  545. $this->assertSame('/just/a/path', clean_param('/just/a/path', PARAM_URL));
  546. // Invalid URLs.
  547. $this->assertSame('', clean_param('funny:thing', PARAM_URL));
  548. $this->assertSame('', clean_param('http://example.ee/sdsf"f', PARAM_URL));
  549. $this->assertSame('', clean_param('javascript://comment%0Aalert(1)', PARAM_URL));
  550. $this->assertSame('', clean_param('rtmp://example.com/livestream', PARAM_URL));
  551. $this->assertSame('', clean_param('rtmp://example.com/live&foo', PARAM_URL));
  552. $this->assertSame('', clean_param('rtmp://example.com/fms&mp4:path/to/file.mp4', PARAM_URL));
  553. $this->assertSame('', clean_param('mailto:support@moodle.org', PARAM_URL));
  554. $this->assertSame('', clean_param('mailto:support@moodle.org?subject=Hello%20Moodle', PARAM_URL));
  555. $this->assertSame('', clean_param('mailto:support@moodle.org?subject=Hello%20Moodle&cc=feedback@moodle.org', PARAM_URL));
  556. }
  557. public function test_clean_param_localurl() {
  558. global $CFG;
  559. $this->resetAfterTest();
  560. // External, invalid.
  561. $this->assertSame('', clean_param('funny:thing', PARAM_LOCALURL));
  562. $this->assertSame('', clean_param('http://google.com/', PARAM_LOCALURL));
  563. $this->assertSame('', clean_param('https://google.com/?test=true', PARAM_LOCALURL));
  564. $this->assertSame('', clean_param('http://some.very.long.and.silly.domain/with/a/path/', PARAM_LOCALURL));
  565. // Local absolute.
  566. $this->assertSame(clean_param($CFG->wwwroot, PARAM_LOCALURL), $CFG->wwwroot);
  567. $this->assertSame($CFG->wwwroot . '/with/something?else=true',
  568. clean_param($CFG->wwwroot . '/with/something?else=true', PARAM_LOCALURL));
  569. // Local relative.
  570. $this->assertSame('/just/a/path', clean_param('/just/a/path', PARAM_LOCALURL));
  571. $this->assertSame('course/view.php?id=3', clean_param('course/view.php?id=3', PARAM_LOCALURL));
  572. // Local absolute HTTPS in a non HTTPS site.
  573. $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); // Need to simulate non-https site.
  574. $httpsroot = str_replace('http:', 'https:', $CFG->wwwroot);
  575. $this->assertSame('', clean_param($httpsroot, PARAM_LOCALURL));
  576. $this->assertSame('', clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL));
  577. // Local absolute HTTPS in a HTTPS site.
  578. $CFG->wwwroot = str_replace('http:', 'https:', $CFG->wwwroot);
  579. $httpsroot = $CFG->wwwroot;
  580. $this->assertSame($httpsroot, clean_param($httpsroot, PARAM_LOCALURL));
  581. $this->assertSame($httpsroot . '/with/something?else=true',
  582. clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL));
  583. // Test open redirects are not possible.
  584. $CFG->wwwroot = 'http://www.example.com';
  585. $this->assertSame('', clean_param('http://www.example.com.evil.net/hack.php', PARAM_LOCALURL));
  586. $CFG->wwwroot = 'https://www.example.com';
  587. $this->assertSame('', clean_param('https://www.example.com.evil.net/hack.php', PARAM_LOCALURL));
  588. }
  589. public function test_clean_param_file() {
  590. $this->assertSame('correctfile.txt', clean_param('correctfile.txt', PARAM_FILE));
  591. $this->assertSame('badfile.txt', clean_param('b\'a<d`\\/fi:l>e.t"x|t', PARAM_FILE));
  592. $this->assertSame('..parentdirfile.txt', clean_param('../parentdirfile.txt', PARAM_FILE));
  593. $this->assertSame('....grandparentdirfile.txt', clean_param('../../grandparentdirfile.txt', PARAM_FILE));
  594. $this->assertSame('..winparentdirfile.txt', clean_param('..\winparentdirfile.txt', PARAM_FILE));
  595. $this->assertSame('....wingrandparentdir.txt', clean_param('..\..\wingrandparentdir.txt', PARAM_FILE));
  596. $this->assertSame('myfile.a.b.txt', clean_param('myfile.a.b.txt', PARAM_FILE));
  597. $this->assertSame('myfile..a..b.txt', clean_param('myfile..a..b.txt', PARAM_FILE));
  598. $this->assertSame('myfile.a..b...txt', clean_param('myfile.a..b...txt', PARAM_FILE));
  599. $this->assertSame('myfile.a.txt', clean_param('myfile.a.txt', PARAM_FILE));
  600. $this->assertSame('myfile...txt', clean_param('myfile...txt', PARAM_FILE));
  601. $this->assertSame('...jpg', clean_param('...jpg', PARAM_FILE));
  602. $this->assertSame('.a.b.', clean_param('.a.b.', PARAM_FILE));
  603. $this->assertSame('', clean_param('.', PARAM_FILE));
  604. $this->assertSame('', clean_param('..', PARAM_FILE));
  605. $this->assertSame('...', clean_param('...', PARAM_FILE));
  606. $this->assertSame('. . . .', clean_param('. . . .', PARAM_FILE));
  607. $this->assertSame('dontrtrim.me. .. .. . ', clean_param('dontrtrim.me. .. .. . ', PARAM_FILE));
  608. $this->assertSame(' . .dontltrim.me', clean_param(' . .dontltrim.me', PARAM_FILE));
  609. $this->assertSame('here is a tab.txt', clean_param("here is a tab\t.txt", PARAM_FILE));
  610. $this->assertSame('here is a linebreak.txt', clean_param("here is a line\r\nbreak.txt", PARAM_FILE));
  611. // The following behaviours have been maintained although they seem a little odd.
  612. $this->assertSame('funnything', clean_param('funny:thing', PARAM_FILE));
  613. $this->assertSame('.currentdirfile.txt', clean_param('./currentdirfile.txt', PARAM_FILE));
  614. $this->assertSame('ctempwindowsfile.txt', clean_param('c:\temp\windowsfile.txt', PARAM_FILE));
  615. $this->assertSame('homeuserlinuxfile.txt', clean_param('/home/user/linuxfile.txt', PARAM_FILE));
  616. $this->assertSame('~myfile.txt', clean_param('~/myfile.txt', PARAM_FILE));
  617. }
  618. public function test_clean_param_path() {
  619. $this->assertSame('correctfile.txt', clean_param('correctfile.txt', PARAM_PATH));
  620. $this->assertSame('bad/file.txt', clean_param('b\'a<d`\\/fi:l>e.t"x|t', PARAM_PATH));
  621. $this->assertSame('/parentdirfile.txt', clean_param('../parentdirfile.txt', PARAM_PATH));
  622. $this->assertSame('/grandparentdirfile.txt', clean_param('../../grandparentdirfile.txt', PARAM_PATH));
  623. $this->assertSame('/winparentdirfile.txt', clean_param('..\winparentdirfile.txt', PARAM_PATH));
  624. $this->assertSame('/wingrandparentdir.txt', clean_param('..\..\wingrandparentdir.txt', PARAM_PATH));
  625. $this->assertSame('funnything', clean_param('funny:thing', PARAM_PATH));
  626. $this->assertSame('./here', clean_param('./././here', PARAM_PATH));
  627. $this->assertSame('./currentdirfile.txt', clean_param('./currentdirfile.txt', PARAM_PATH));
  628. $this->assertSame('c/temp/windowsfile.txt', clean_param('c:\temp\windowsfile.txt', PARAM_PATH));
  629. $this->assertSame('/home/user/linuxfile.txt', clean_param('/home/user/linuxfile.txt', PARAM_PATH));
  630. $this->assertSame('/home../user ./.linuxfile.txt', clean_param('/home../user ./.linuxfile.txt', PARAM_PATH));
  631. $this->assertSame('~/myfile.txt', clean_param('~/myfile.txt', PARAM_PATH));
  632. $this->assertSame('~/myfile.txt', clean_param('~/../myfile.txt', PARAM_PATH));
  633. $this->assertSame('/..b../.../myfile.txt', clean_param('/..b../.../myfile.txt', PARAM_PATH));
  634. $this->assertSame('..b../.../myfile.txt', clean_param('..b../.../myfile.txt', PARAM_PATH));
  635. $this->assertSame('/super/slashes/', clean_param('/super//slashes///', PARAM_PATH));
  636. }
  637. public function test_clean_param_username() {
  638. global $CFG;
  639. $currentstatus = $CFG->extendedusernamechars;
  640. // Run tests with extended character == false;.
  641. $CFG->extendedusernamechars = false;
  642. $this->assertSame('johndoe123', clean_param('johndoe123', PARAM_USERNAME) );
  643. $this->assertSame('john.doe', clean_param('john.doe', PARAM_USERNAME));
  644. $this->assertSame('john-doe', clean_param('john-doe', PARAM_USERNAME));
  645. $this->assertSame('john-doe', clean_param('john- doe', PARAM_USERNAME));
  646. $this->assertSame('john_doe', clean_param('john_doe', PARAM_USERNAME));
  647. $this->assertSame('john@doe', clean_param('john@doe', PARAM_USERNAME));
  648. $this->assertSame('johndoe', clean_param('john~doe', PARAM_USERNAME));
  649. $this->assertSame('johndoe', clean_param('john´doe', PARAM_USERNAME));
  650. $this->assertSame(clean_param('john# $%&()+_^', PARAM_USERNAME), 'john_');
  651. $this->assertSame(clean_param(' john# $%&()+_^ ', PARAM_USERNAME), 'john_');
  652. $this->assertSame(clean_param('john#$%&() ', PARAM_USERNAME), 'john');
  653. $this->assertSame('johnd', clean_param('JOHNdóé ', PARAM_USERNAME));
  654. $this->assertSame(clean_param('john.,:;-_/|\ñÑ[]A_X-,D {} ~!@#$%^&*()_+ ?><[] ščřžžý ?ýáž?žý??šdoe ', PARAM_USERNAME), 'john.-_a_x-d@_doe');
  655. // Test success condition, if extendedusernamechars == ENABLE;.
  656. $CFG->extendedusernamechars = true;
  657. $this->assertSame('john_doe', clean_param('john_doe', PARAM_USERNAME));
  658. $this->assertSame('john@doe', clean_param('john@doe', PARAM_USERNAME));
  659. $this->assertSame(clean_param('john# $%&()+_^', PARAM_USERNAME), 'john# $%&()+_^');
  660. $this->assertSame(clean_param(' john# $%&()+_^ ', PARAM_USERNAME), 'john# $%&()+_^');
  661. $this->assertSame('john~doe', clean_param('john~doe', PARAM_USERNAME));
  662. $this->assertSame('john´doe', clean_param('joHN´doe', PARAM_USERNAME));
  663. $this->assertSame('johndoe', clean_param('johnDOE', PARAM_USERNAME));
  664. $this->assertSame('johndóé', clean_param('johndóé ', PARAM_USERNAME));
  665. $CFG->extendedusernamechars = $currentstatus;
  666. }
  667. public function test_clean_param_stringid() {
  668. // Test string identifiers validation.
  669. // Valid strings.
  670. $this->assertSame('validstring', clean_param('validstring', PARAM_STRINGID));
  671. $this->assertSame('mod/foobar:valid_capability', clean_param('mod/foobar:valid_capability', PARAM_STRINGID));
  672. $this->assertSame('CZ', clean_param('CZ', PARAM_STRINGID));
  673. $this->assertSame('application/vnd.ms-powerpoint', clean_param('application/vnd.ms-powerpoint', PARAM_STRINGID));
  674. $this->assertSame('grade2', clean_param('grade2', PARAM_STRINGID));
  675. // Invalid strings.
  676. $this->assertSame('', clean_param('trailing ', PARAM_STRINGID));
  677. $this->assertSame('', clean_param('space bar', PARAM_STRINGID));
  678. $this->assertSame('', clean_param('0numeric', PARAM_STRINGID));
  679. $this->assertSame('', clean_param('*', PARAM_STRINGID));
  680. $this->assertSame('', clean_param(' ', PARAM_STRINGID));
  681. }
  682. public function test_clean_param_timezone() {
  683. // Test timezone validation.
  684. $testvalues = array (
  685. 'America/Jamaica' => 'America/Jamaica',
  686. 'America/Argentina/Cordoba' => 'America/Argentina/Cordoba',
  687. 'America/Port-au-Prince' => 'America/Port-au-Prince',
  688. 'America/Argentina/Buenos_Aires' => 'America/Argentina/Buenos_Aires',
  689. 'PST8PDT' => 'PST8PDT',
  690. 'Wrong.Value' => '',
  691. 'Wrong/.Value' => '',
  692. 'Wrong(Value)' => '',
  693. '0' => '0',
  694. '0.0' => '0.0',
  695. '0.5' => '0.5',
  696. '9.0' => '9.0',
  697. '-9.0' => '-9.0',
  698. '+9.0' => '+9.0',
  699. '9.5' => '9.5',
  700. '-9.5' => '-9.5',
  701. '+9.5' => '+9.5',
  702. '12.0' => '12.0',
  703. '-12.0' => '-12.0',
  704. '+12.0' => '+12.0',
  705. '12.5' => '12.5',
  706. '-12.5' => '-12.5',
  707. '+12.5' => '+12.5',
  708. '13.0' => '13.0',
  709. '-13.0' => '-13.0',
  710. '+13.0' => '+13.0',
  711. '13.5' => '',
  712. '+13.5' => '',
  713. '-13.5' => '',
  714. '0.2' => '');
  715. foreach ($testvalues as $testvalue => $expectedvalue) {
  716. $actualvalue = clean_param($testvalue, PARAM_TIMEZONE);
  717. $this->assertEquals($expectedvalue, $actualvalue);
  718. }
  719. }
  720. public function test_validate_param() {
  721. try {
  722. $param = validate_param('11a', PARAM_INT);
  723. $this->fail('invalid_parameter_exception expected');
  724. } catch (moodle_exception $ex) {
  725. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  726. }
  727. $param = validate_param('11', PARAM_INT);
  728. $this->assertSame(11, $param);
  729. try {
  730. $param = validate_param(null, PARAM_INT, false);
  731. $this->fail('invalid_parameter_exception expected');
  732. } catch (moodle_exception $ex) {
  733. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  734. }
  735. $param = validate_param(null, PARAM_INT, true);
  736. $this->assertSame(null, $param);
  737. try {
  738. $param = validate_param(array(), PARAM_INT);
  739. $this->fail('invalid_parameter_exception expected');
  740. } catch (moodle_exception $ex) {
  741. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  742. }
  743. try {
  744. $param = validate_param(new stdClass, PARAM_INT);
  745. $this->fail('invalid_parameter_exception expected');
  746. } catch (moodle_exception $ex) {
  747. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  748. }
  749. $param = validate_param('1.0', PARAM_FLOAT);
  750. $this->assertSame(1.0, $param);
  751. // Make sure valid floats do not cause exception.
  752. validate_param(1.0, PARAM_FLOAT);
  753. validate_param(10, PARAM_FLOAT);
  754. validate_param('0', PARAM_FLOAT);
  755. validate_param('119813454.545464564564546564545646556564465465456465465465645645465645645645', PARAM_FLOAT);
  756. validate_param('011.1', PARAM_FLOAT);
  757. validate_param('11', PARAM_FLOAT);
  758. validate_param('+.1', PARAM_FLOAT);
  759. validate_param('-.1', PARAM_FLOAT);
  760. validate_param('1e10', PARAM_FLOAT);
  761. validate_param('.1e+10', PARAM_FLOAT);
  762. validate_param('1E-1', PARAM_FLOAT);
  763. try {
  764. $param = validate_param('1,2', PARAM_FLOAT);
  765. $this->fail('invalid_parameter_exception expected');
  766. } catch (moodle_exception $ex) {
  767. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  768. }
  769. try {
  770. $param = validate_param('', PARAM_FLOAT);
  771. $this->fail('invalid_parameter_exception expected');
  772. } catch (moodle_exception $ex) {
  773. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  774. }
  775. try {
  776. $param = validate_param('.', PARAM_FLOAT);
  777. $this->fail('invalid_parameter_exception expected');
  778. } catch (moodle_exception $ex) {
  779. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  780. }
  781. try {
  782. $param = validate_param('e10', PARAM_FLOAT);
  783. $this->fail('invalid_parameter_exception expected');
  784. } catch (moodle_exception $ex) {
  785. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  786. }
  787. try {
  788. $param = validate_param('abc', PARAM_FLOAT);
  789. $this->fail('invalid_parameter_exception expected');
  790. } catch (moodle_exception $ex) {
  791. $this->assertInstanceOf('invalid_parameter_exception', $ex);
  792. }
  793. }
  794. public function test_shorten_text_no_tags_already_short_enough() {
  795. // ......12345678901234567890123456.
  796. $text = "short text already no tags";
  797. $this->assertSame($text, shorten_text($text));
  798. }
  799. public function test_shorten_text_with_tags_already_short_enough() {
  800. // .........123456...7890....12345678.......901234567.
  801. $text = "<p>short <b>text</b> already</p><p>with tags</p>";
  802. $this->assertSame($text, shorten_text($text));
  803. }
  804. public function test_shorten_text_no_tags_needs_shortening() {
  805. // Default truncation is after 30 chars, but allowing 3 for the final '...'.
  806. // ......12345678901234567890123456789023456789012345678901234.
  807. $text = "long text without any tags blah de blah blah blah what";
  808. $this->assertSame('long text without any tags ...', shorten_text($text));
  809. }
  810. public function test_shorten_text_with_tags_needs_shortening() {
  811. // .......................................123456789012345678901234567890...
  812. $text = "<div class='frog'><p><blockquote>Long text with tags that will ".
  813. "be chopped off but <b>should be added back again</b></blockquote></p></div>";
  814. $this->assertEquals("<div class='frog'><p><blockquote>Long text with " .
  815. "tags that ...</blockquote></p></div>", shorten_text($text));
  816. }
  817. public function test_shorten_text_with_tags_and_html_comment() {
  818. $text = "<div class='frog'><p><blockquote><!--[if !IE]><!-->Long text with ".
  819. "tags that will<!--<![endif]--> ".
  820. "be chopped off but <b>should be added back again</b></blockquote></p></div>";
  821. $this->assertEquals("<div class='frog'><p><blockquote><!--[if !IE]><!-->Long text with " .
  822. "tags that ...<!--<![endif]--></blockquote></p></div>", shorten_text($text));
  823. }
  824. public function test_shorten_text_with_entities() {
  825. // Remember to allow 3 chars for the final '...'.
  826. // ......123456789012345678901234567_____890...
  827. $text = "some text which shouldn't &nbsp; break there";
  828. $this->assertSame("some text which shouldn't &nbsp; ...", shorten_text($text, 31));
  829. $this->assertSame("some text which shouldn't &nbsp;...", shorten_text($text, 30));
  830. $this->assertSame("some text which shouldn't ...", shorten_text($text, 29));
  831. }
  832. public function test_shorten_text_known_tricky_case() {
  833. // This case caused a bug up to 1.9.5
  834. // ..........123456789012345678901234567890123456789.....0_____1___…

Large files files are truncated, but you can click here to view the full file