Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 * Weblib tests. 19 * 20 * @package core 21 * @category phpunit 22 * @copyright © 2006 The Open University 23 * @author T.J.Hunt@open.ac.uk 24 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 30 class core_weblib_testcase extends advanced_testcase { 31 32 public function test_format_string() { 33 global $CFG; 34 35 // Ampersands. 36 $this->assertSame("& &&&&& &&", format_string("& &&&&& &&")); 37 $this->assertSame("ANother & &&&&& Category", format_string("ANother & &&&&& Category")); 38 $this->assertSame("ANother & &&&&& Category", format_string("ANother & &&&&& Category", true)); 39 $this->assertSame("Nick's Test Site & Other things", format_string("Nick's Test Site & Other things", true)); 40 $this->assertSame("& < > \" '", format_string("& < > \" '", true, ['escape' => false])); 41 42 // String entities. 43 $this->assertSame(""", format_string(""")); 44 45 // Digital entities. 46 $this->assertSame("&11234;", format_string("&11234;")); 47 48 // Unicode entities. 49 $this->assertSame("ᅻ", format_string("ᅻ")); 50 51 // < and > signs. 52 $originalformatstringstriptags = $CFG->formatstringstriptags; 53 54 $CFG->formatstringstriptags = false; 55 $this->assertSame('x < 1', format_string('x < 1')); 56 $this->assertSame('x > 1', format_string('x > 1')); 57 $this->assertSame('x < 1 and x > 0', format_string('x < 1 and x > 0')); 58 59 $CFG->formatstringstriptags = true; 60 $this->assertSame('x < 1', format_string('x < 1')); 61 $this->assertSame('x > 1', format_string('x > 1')); 62 $this->assertSame('x < 1 and x > 0', format_string('x < 1 and x > 0')); 63 64 $CFG->formatstringstriptags = $originalformatstringstriptags; 65 } 66 67 /** 68 * The format string static caching should include the filters option to make 69 * sure filters are correctly applied when requested. 70 */ 71 public function test_format_string_static_caching_with_filters() { 72 global $CFG; 73 74 $this->resetAfterTest(true); 75 $this->setAdminUser(); 76 $generator = $this->getDataGenerator(); 77 $course = $generator->create_course(); 78 $user = $generator->create_user(); 79 $rawstring = 'Shortname <a href="#">link</a> curseword'; 80 $expectednofilter = strip_links($rawstring); 81 $expectedfilter = 'Shortname link \*\**'; 82 $striplinks = true; 83 $context = context_course::instance($course->id); 84 $options = [ 85 'context' => $context, 86 'escape' => true, 87 'filter' => false 88 ]; 89 90 $this->setUser($user); 91 92 // Format the string without filters. It should just strip the 93 // links. 94 $nofilterresult = format_string($rawstring, $striplinks, $options); 95 $this->assertEquals($expectednofilter, $nofilterresult); 96 97 // Add the censor filter. Make sure it's enabled globally. 98 $CFG->filterall = true; 99 $CFG->stringfilters = 'censor'; 100 $CFG->filter_censor_badwords = 'curseword'; 101 filter_set_global_state('censor', TEXTFILTER_ON); 102 filter_set_local_state('censor', $context->id, TEXTFILTER_ON); 103 // This time we want to apply the filters. 104 $options['filter'] = true; 105 $filterresult = format_string($rawstring, $striplinks, $options); 106 $this->assertMatchesRegularExpression("/$expectedfilter/", $filterresult); 107 108 filter_set_local_state('censor', $context->id, TEXTFILTER_OFF); 109 110 // Confirm that we get back the cached string. The result should be 111 // the same as the filtered text above even though we've disabled the 112 // censor filter in between. 113 $cachedresult = format_string($rawstring, $striplinks, $options); 114 $this->assertMatchesRegularExpression("/$expectedfilter/", $cachedresult); 115 } 116 117 public function test_s() { 118 // Special cases. 119 $this->assertSame('0', s(0)); 120 $this->assertSame('0', s('0')); 121 $this->assertSame('0', s(false)); 122 $this->assertSame('', s(null)); 123 124 // Normal cases. 125 $this->assertSame('This Breaks " Strict', s('This Breaks " Strict')); 126 $this->assertSame('This Breaks <a>" Strict</a>', s('This Breaks <a>" Strict</a>')); 127 128 // Unicode characters. 129 $this->assertSame('Café', s('Café')); 130 $this->assertSame('一, 二, 三', s('一, 二, 三')); 131 132 // Don't escape already-escaped numeric entities. (Note, this behaviour 133 // may not be desirable. Perhaps we should remove these tests and that 134 // functionality, but we can only do that if we understand why it was added.) 135 $this->assertSame('An entity: ৿.', s('An entity: ৿.')); 136 $this->assertSame('An entity: б.', s('An entity: б.')); 137 $this->assertSame('An entity: &amp;.', s('An entity: &.')); 138 $this->assertSame('Not an entity: &amp;#x09ff;.', s('Not an entity: &#x09ff;.')); 139 140 // Test all ASCII characters (0-127). 141 for ($i = 0; $i <= 127; $i++) { 142 $character = chr($i); 143 $result = s($character); 144 switch ($character) { 145 case '"' : 146 $this->assertSame('"', $result); 147 break; 148 case '&' : 149 $this->assertSame('&', $result); 150 break; 151 case "'" : 152 $this->assertSame(''', $result); 153 break; 154 case '<' : 155 $this->assertSame('<', $result); 156 break; 157 case '>' : 158 $this->assertSame('>', $result); 159 break; 160 default: 161 $this->assertSame($character, $result); 162 break; 163 } 164 } 165 } 166 167 public function test_format_text_email() { 168 $this->assertSame("This is a TEST\n", 169 format_text_email('<p>This is a <strong>test</strong></p>', FORMAT_HTML)); 170 $this->assertSame("This is a TEST\n", 171 format_text_email('<p class="frogs">This is a <strong class=\'fishes\'>test</strong></p>', FORMAT_HTML)); 172 $this->assertSame('& so is this', 173 format_text_email('& so is this', FORMAT_HTML)); 174 $this->assertSame('Two bullets: ' . core_text::code2utf8(8226) . ' ' . core_text::code2utf8(8226), 175 format_text_email('Two bullets: • •', FORMAT_HTML)); 176 $this->assertSame(core_text::code2utf8(0x7fd2).core_text::code2utf8(0x7fd2), 177 format_text_email('習習', FORMAT_HTML)); 178 } 179 180 public function test_obfuscate_email() { 181 $email = 'some.user@example.com'; 182 $obfuscated = obfuscate_email($email); 183 $this->assertNotSame($email, $obfuscated); 184 $back = core_text::entities_to_utf8(urldecode($email), true); 185 $this->assertSame($email, $back); 186 } 187 188 public function test_obfuscate_text() { 189 $text = 'Žluťoučký koníček 32131'; 190 $obfuscated = obfuscate_text($text); 191 $this->assertNotSame($text, $obfuscated); 192 $back = core_text::entities_to_utf8($obfuscated, true); 193 $this->assertSame($text, $back); 194 } 195 196 public function test_highlight() { 197 $this->assertSame('This is <span class="highlight">good</span>', 198 highlight('good', 'This is good')); 199 200 $this->assertSame('<span class="highlight">span</span>', 201 highlight('SpaN', 'span')); 202 203 $this->assertSame('<span class="highlight">SpaN</span>', 204 highlight('span', 'SpaN')); 205 206 $this->assertSame('<span><span class="highlight">span</span></span>', 207 highlight('span', '<span>span</span>')); 208 209 $this->assertSame('He <span class="highlight">is</span> <span class="highlight">good</span>', 210 highlight('good is', 'He is good')); 211 212 $this->assertSame('This is <span class="highlight">good</span>', 213 highlight('+good', 'This is good')); 214 215 $this->assertSame('This is good', 216 highlight('-good', 'This is good')); 217 218 $this->assertSame('This is goodness', 219 highlight('+good', 'This is goodness')); 220 221 $this->assertSame('This is <span class="highlight">good</span>ness', 222 highlight('good', 'This is goodness')); 223 224 $this->assertSame('<p><b>test</b> <b>1</b></p><p><b>1</b></p>', 225 highlight('test 1', '<p>test 1</p><p>1</p>', false, '<b>', '</b>')); 226 227 $this->assertSame('<p><b>test</b> <b>1</b></p><p><b>1</b></p>', 228 highlight('test +1', '<p>test 1</p><p>1</p>', false, '<b>', '</b>')); 229 230 $this->assertSame('<p><b>test</b> 1</p><p>1</p>', 231 highlight('test -1', '<p>test 1</p><p>1</p>', false, '<b>', '</b>')); 232 } 233 234 public function test_replace_ampersands() { 235 $this->assertSame("This & that ", replace_ampersands_not_followed_by_entity("This & that ")); 236 $this->assertSame("This &nbsp that ", replace_ampersands_not_followed_by_entity("This   that ")); 237 } 238 239 public function test_strip_links() { 240 $this->assertSame('this is a link', strip_links('this is a <a href="http://someaddress.com/query">link</a>')); 241 } 242 243 public function test_wikify_links() { 244 $this->assertSame('this is a link [ http://someaddress.com/query ]', wikify_links('this is a <a href="http://someaddress.com/query">link</a>')); 245 } 246 247 public function test_clean_text() { 248 $text = "lala <applet>xx</applet>"; 249 $this->assertSame($text, clean_text($text, FORMAT_PLAIN)); 250 $this->assertSame('lala xx', clean_text($text, FORMAT_MARKDOWN)); 251 $this->assertSame('lala xx', clean_text($text, FORMAT_MOODLE)); 252 $this->assertSame('lala xx', clean_text($text, FORMAT_HTML)); 253 } 254 255 public function test_qualified_me() { 256 global $PAGE, $FULLME, $CFG; 257 $this->resetAfterTest(); 258 259 $PAGE = new moodle_page(); 260 261 $FULLME = $CFG->wwwroot.'/course/view.php?id=1&xx=yy'; 262 $this->assertSame($FULLME, qualified_me()); 263 264 $PAGE->set_url('/course/view.php', array('id'=>1)); 265 $this->assertSame($CFG->wwwroot.'/course/view.php?id=1', qualified_me()); 266 } 267 268 public function test_null_progres_trace() { 269 $this->resetAfterTest(false); 270 271 $trace = new null_progress_trace(); 272 $trace->output('do'); 273 $trace->output('re', 1); 274 $trace->output('mi', 2); 275 $trace->finished(); 276 $output = ob_get_contents(); 277 $this->assertSame('', $output); 278 $this->expectOutputString(''); 279 } 280 281 public function test_text_progres_trace() { 282 $this->resetAfterTest(false); 283 284 $trace = new text_progress_trace(); 285 $trace->output('do'); 286 $trace->output('re', 1); 287 $trace->output('mi', 2); 288 $trace->finished(); 289 $this->expectOutputString("do\n re\n mi\n"); 290 } 291 292 public function test_html_progres_trace() { 293 $this->resetAfterTest(false); 294 295 $trace = new html_progress_trace(); 296 $trace->output('do'); 297 $trace->output('re', 1); 298 $trace->output('mi', 2); 299 $trace->finished(); 300 $this->expectOutputString("<p>do</p>\n<p>  re</p>\n<p>    mi</p>\n"); 301 } 302 303 public function test_html_list_progress_trace() { 304 $this->resetAfterTest(false); 305 306 $trace = new html_list_progress_trace(); 307 $trace->output('do'); 308 $trace->output('re', 1); 309 $trace->output('mi', 2); 310 $trace->finished(); 311 $this->expectOutputString("<ul>\n<li>do<ul>\n<li>re<ul>\n<li>mi</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n"); 312 } 313 314 public function test_progres_trace_buffer() { 315 $this->resetAfterTest(false); 316 317 $trace = new progress_trace_buffer(new html_progress_trace()); 318 ob_start(); 319 $trace->output('do'); 320 $trace->output('re', 1); 321 $trace->output('mi', 2); 322 $trace->finished(); 323 $output = ob_get_contents(); 324 ob_end_clean(); 325 $this->assertSame("<p>do</p>\n<p>  re</p>\n<p>    mi</p>\n", $output); 326 $this->assertSame($output, $trace->get_buffer()); 327 328 $trace = new progress_trace_buffer(new html_progress_trace(), false); 329 $trace->output('do'); 330 $trace->output('re', 1); 331 $trace->output('mi', 2); 332 $trace->finished(); 333 $this->assertSame("<p>do</p>\n<p>  re</p>\n<p>    mi</p>\n", $trace->get_buffer()); 334 $this->assertSame("<p>do</p>\n<p>  re</p>\n<p>    mi</p>\n", $trace->get_buffer()); 335 $trace->reset_buffer(); 336 $this->assertSame('', $trace->get_buffer()); 337 $this->expectOutputString(''); 338 } 339 340 public function test_combined_progres_trace() { 341 $this->resetAfterTest(false); 342 343 $trace1 = new progress_trace_buffer(new html_progress_trace(), false); 344 $trace2 = new progress_trace_buffer(new text_progress_trace(), false); 345 346 $trace = new combined_progress_trace(array($trace1, $trace2)); 347 $trace->output('do'); 348 $trace->output('re', 1); 349 $trace->output('mi', 2); 350 $trace->finished(); 351 $this->assertSame("<p>do</p>\n<p>  re</p>\n<p>    mi</p>\n", $trace1->get_buffer()); 352 $this->assertSame("do\n re\n mi\n", $trace2->get_buffer()); 353 $this->expectOutputString(''); 354 } 355 356 public function test_set_debugging() { 357 global $CFG; 358 359 $this->resetAfterTest(); 360 361 $this->assertEquals(DEBUG_DEVELOPER, $CFG->debug); 362 $this->assertTrue($CFG->debugdeveloper); 363 $this->assertNotEmpty($CFG->debugdisplay); 364 365 set_debugging(DEBUG_DEVELOPER, true); 366 $this->assertEquals(DEBUG_DEVELOPER, $CFG->debug); 367 $this->assertTrue($CFG->debugdeveloper); 368 $this->assertNotEmpty($CFG->debugdisplay); 369 370 set_debugging(DEBUG_DEVELOPER, false); 371 $this->assertEquals(DEBUG_DEVELOPER, $CFG->debug); 372 $this->assertTrue($CFG->debugdeveloper); 373 $this->assertEmpty($CFG->debugdisplay); 374 375 set_debugging(-1); 376 $this->assertEquals(-1, $CFG->debug); 377 $this->assertTrue($CFG->debugdeveloper); 378 379 set_debugging(DEBUG_ALL); 380 $this->assertEquals(DEBUG_ALL, $CFG->debug); 381 $this->assertFalse($CFG->debugdeveloper); 382 383 set_debugging(DEBUG_NORMAL); 384 $this->assertEquals(DEBUG_NORMAL, $CFG->debug); 385 $this->assertFalse($CFG->debugdeveloper); 386 387 set_debugging(DEBUG_MINIMAL); 388 $this->assertEquals(DEBUG_MINIMAL, $CFG->debug); 389 $this->assertFalse($CFG->debugdeveloper); 390 391 set_debugging(DEBUG_NONE); 392 $this->assertEquals(DEBUG_NONE, $CFG->debug); 393 $this->assertFalse($CFG->debugdeveloper); 394 } 395 396 public function test_strip_pluginfile_content() { 397 $source = <<<SOURCE 398 Hello! 399 400 I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. 401 402 URL outside a tag: https://moodle.org/logo/logo-240x60.gif 403 Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif 404 405 External link 1:<img src='https://moodle.org/logo/logo-240x60.gif' alt='Moodle'/> 406 External link 2:<img alt="Moodle" src="https://moodle.org/logo/logo-240x60.gif"/> 407 Internal link 1:<img src='@@PLUGINFILE@@/logo-240x60.gif' alt='Moodle'/> 408 Internal link 2:<img alt="Moodle" src="@@PLUGINFILE@@logo-240x60.gif"/> 409 Anchor link 1:<a href="@@PLUGINFILE@@logo-240x60.gif" alt="bananas">Link text</a> 410 Anchor link 2:<a title="bananas" href="../logo-240x60.gif">Link text</a> 411 Anchor + ext. img:<a title="bananas" href="../logo-240x60.gif"><img alt="Moodle" src="@@PLUGINFILE@@logo-240x60.gif"/></a> 412 Ext. anchor + img:<a href="@@PLUGINFILE@@logo-240x60.gif"><img alt="Moodle" src="https://moodle.org/logo/logo-240x60.gif"/></a> 413 SOURCE; 414 $expected = <<<EXPECTED 415 Hello! 416 417 I'm writing to you from the Moodle Majlis in Muscat, Oman, where we just had several days of Moodle community goodness. 418 419 URL outside a tag: https://moodle.org/logo/logo-240x60.gif 420 Plugin url outside a tag: @@PLUGINFILE@@/logo-240x60.gif 421 422 External link 1:<img src="https://moodle.org/logo/logo-240x60.gif" alt="Moodle" /> 423 External link 2:<img alt="Moodle" src="https://moodle.org/logo/logo-240x60.gif" /> 424 Internal link 1: 425 Internal link 2: 426 Anchor link 1:Link text 427 Anchor link 2:<a title="bananas" href="../logo-240x60.gif">Link text</a> 428 Anchor + ext. img:<a title="bananas" href="../logo-240x60.gif"></a> 429 Ext. anchor + img:<img alt="Moodle" src="https://moodle.org/logo/logo-240x60.gif" /> 430 EXPECTED; 431 $this->assertSame($expected, strip_pluginfile_content($source)); 432 } 433 434 public function test_purify_html_ruby() { 435 436 $this->resetAfterTest(); 437 438 $ruby = 439 "<p><ruby><rb>京都</rb><rp>(</rp><rt>きょうと</rt><rp>)</rp></ruby>は" . 440 "<ruby><rb>日本</rb><rp>(</rp><rt>にほん</rt><rp>)</rp></ruby>の" . 441 "<ruby><rb>都</rb><rp>(</rp><rt>みやこ</rt><rp>)</rp></ruby>です。</p>"; 442 $illegal = '<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>'; 443 444 $cleaned = purify_html($ruby . $illegal); 445 $this->assertEquals($ruby, $cleaned); 446 447 } 448 449 /** 450 * Tests for content_to_text. 451 * 452 * @param string $content The content 453 * @param int|false $format The content format 454 * @param string $expected Expected value 455 * @dataProvider provider_content_to_text 456 */ 457 public function test_content_to_text($content, $format, $expected) { 458 $content = content_to_text($content, $format); 459 $this->assertEquals($expected, $content); 460 } 461 462 /** 463 * Data provider for test_content_to_text. 464 */ 465 public static function provider_content_to_text() { 466 return array( 467 array('asd', false, 'asd'), 468 // Trim '\r\n '. 469 array("Note that:\n\n3 > 1 ", FORMAT_PLAIN, "Note that:\n\n3 > 1"), 470 array("Note that:\n\n3 > 1\r\n", FORMAT_PLAIN, "Note that:\n\n3 > 1"), 471 // Multiple spaces to one. 472 array('<span class="eheh">京都</span> -> hehe', FORMAT_HTML, '京都 -> hehe'), 473 array('<span class="eheh">京都</span> -> hehe', false, '京都 -> hehe'), 474 array('asd asd', false, 'asd asd'), 475 // From markdown to html and html to text. 476 array('asd __lera__ con la', FORMAT_MARKDOWN, 'asd LERA con la'), 477 // HTML to text. 478 array('<p class="frogs">This is a <strong class=\'fishes\'>test</strong></p>', FORMAT_HTML, 'This is a TEST'), 479 array("<span lang='en' class='multilang'>english</span> 480 <span lang='ca' class='multilang'>català</span> 481 <span lang='es' class='multilang'>español</span> 482 <span lang='fr' class='multilang'>français</span>", FORMAT_HTML, "english català español français") 483 ); 484 } 485 486 /** 487 * Data provider for validate_email() function. 488 * 489 * @return array Returns aray of test data for the test_validate_email function 490 */ 491 public function data_validate_email() { 492 return [ 493 // Test addresses that should pass. 494 [ 495 'email' => 'moodle@example.com', 496 'result' => true 497 ], 498 [ 499 'email' => 'moodle@localhost.local', 500 'result' => true 501 ], 502 [ 503 'email' => 'verp_email+is=mighty@moodle.org', 504 'result' => true 505 ], 506 [ 507 'email' => "but_potentially'dangerous'too@example.org", 508 'result' => true 509 ], 510 [ 511 'email' => 'posts+AAAAAAAAAAIAAAAAAAAGQQAAAAABFSXz1eM/P/lR2bYyljM+@posts.moodle.org', 512 'result' => true 513 ], 514 515 // Test addresses that should NOT pass. 516 [ 517 'email' => 'moodle@localhost', 518 'result' => false 519 ], 520 [ 521 'email' => '"attacker\\" -oQ/tmp/ -X/var/www/vhost/moodle/backdoor.php some"@email.com', 522 'result' => false 523 ], 524 [ 525 'email' => "moodle@example.com>\r\nRCPT TO:<victim@example.com", 526 'result' => false 527 ], 528 [ 529 'email' => 'greater>than@example.com', 530 'result' => false 531 ], 532 [ 533 'email' => 'less<than@example.com', 534 'result' => false 535 ], 536 [ 537 'email' => '"this<is>validbutwerejectit"@example.com', 538 'result' => false 539 ], 540 541 // Extra email addresses from Wikipedia page on Email Addresses. 542 // Valid. 543 [ 544 'email' => 'simple@example.com', 545 'result' => true 546 ], 547 [ 548 'email' => 'very.common@example.com', 549 'result' => true 550 ], 551 [ 552 'email' => 'disposable.style.email.with+symbol@example.com', 553 'result' => true 554 ], 555 [ 556 'email' => 'other.email-with-hyphen@example.com', 557 'result' => true 558 ], 559 [ 560 'email' => 'fully-qualified-domain@example.com', 561 'result' => true 562 ], 563 [ 564 'email' => 'user.name+tag+sorting@example.com', 565 'result' => true 566 ], 567 // One-letter local-part. 568 [ 569 'email' => 'x@example.com', 570 'result' => true 571 ], 572 [ 573 'email' => 'example-indeed@strange-example.com', 574 'result' => true 575 ], 576 // See the List of Internet top-level domains. 577 [ 578 'email' => 'example@s.example', 579 'result' => true 580 ], 581 // Quoted double dot. 582 [ 583 'email' => '"john..doe"@example.org', 584 'result' => true 585 ], 586 587 // Invalid. 588 // No @ character. 589 [ 590 'email' => 'Abc.example.com', 591 'result' => false 592 ], 593 // Only one @ is allowed outside quotation marks. 594 [ 595 'email' => 'A@b@c@example.com', 596 'result' => false 597 ], 598 // None of the special characters in this local-part are allowed outside quotation marks. 599 [ 600 'email' => 'a"b(c)d,e:f;g<h>i[j\k]l@example.com', 601 'result' => false 602 ], 603 // Quoted strings must be dot separated or the only element making up the local-part. 604 [ 605 'email' => 'just"not"right@example.com', 606 'result' => false 607 ], 608 // Spaces, quotes, and backslashes may only exist when within quoted strings and preceded by a backslash. 609 [ 610 'email' => 'this is"not\allowed@example.com', 611 'result' => false 612 ], 613 // Even if escaped (preceded by a backslash), spaces, quotes, and backslashes must still be contained by quotes. 614 [ 615 'email' => 'this\ still\"not\\allowed@example.com', 616 'result' => false 617 ], 618 // Local part is longer than 64 characters. 619 [ 620 'email' => '1234567890123456789012345678901234567890123456789012345678901234+x@example.com', 621 'result' => false 622 ], 623 ]; 624 } 625 626 /** 627 * Tests valid and invalid email address using the validate_email() function. 628 * 629 * @param string $email the email address to test 630 * @param boolean $result Expected result (true or false) 631 * @dataProvider data_validate_email 632 */ 633 public function test_validate_email($email, $result) { 634 if ($result) { 635 $this->assertTrue(validate_email($email)); 636 } else { 637 $this->assertFalse(validate_email($email)); 638 } 639 } 640 641 /** 642 * Data provider for test_get_file_argument. 643 */ 644 public static function provider_get_file_argument() { 645 return array( 646 // Serving SCORM content w/o HTTP GET params. 647 array(array( 648 'SERVER_SOFTWARE' => 'Apache', 649 'SERVER_PORT' => '80', 650 'REQUEST_METHOD' => 'GET', 651 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html', 652 'SCRIPT_NAME' => '/pluginfile.php', 653 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 654 ), 0, '/3854/mod_scorm/content/1/swf.html'), 655 array(array( 656 'SERVER_SOFTWARE' => 'Apache', 657 'SERVER_PORT' => '80', 658 'REQUEST_METHOD' => 'GET', 659 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html', 660 'SCRIPT_NAME' => '/pluginfile.php', 661 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 662 ), 1, '/3854/mod_scorm/content/1/swf.html'), 663 // Serving SCORM content w/ HTTP GET 'file' as first param. 664 array(array( 665 'SERVER_SOFTWARE' => 'Apache', 666 'SERVER_PORT' => '80', 667 'REQUEST_METHOD' => 'GET', 668 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html?file=video_.swf', 669 'SCRIPT_NAME' => '/pluginfile.php', 670 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 671 ), 0, '/3854/mod_scorm/content/1/swf.html'), 672 array(array( 673 'SERVER_SOFTWARE' => 'Apache', 674 'SERVER_PORT' => '80', 675 'REQUEST_METHOD' => 'GET', 676 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html?file=video_.swf', 677 'SCRIPT_NAME' => '/pluginfile.php', 678 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 679 ), 1, '/3854/mod_scorm/content/1/swf.html'), 680 // Serving SCORM content w/ HTTP GET 'file' not as first param. 681 array(array( 682 'SERVER_SOFTWARE' => 'Apache', 683 'SERVER_PORT' => '80', 684 'REQUEST_METHOD' => 'GET', 685 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html?foo=bar&file=video_.swf', 686 'SCRIPT_NAME' => '/pluginfile.php', 687 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 688 ), 0, '/3854/mod_scorm/content/1/swf.html'), 689 array(array( 690 'SERVER_SOFTWARE' => 'Apache', 691 'SERVER_PORT' => '80', 692 'REQUEST_METHOD' => 'GET', 693 'REQUEST_URI' => '/pluginfile.php/3854/mod_scorm/content/1/swf.html?foo=bar&file=video_.swf', 694 'SCRIPT_NAME' => '/pluginfile.php', 695 'PATH_INFO' => '/3854/mod_scorm/content/1/swf.html', 696 ), 1, '/3854/mod_scorm/content/1/swf.html'), 697 // Serving content from a generic activity w/ HTTP GET 'file', still forcing slash arguments. 698 array(array( 699 'SERVER_SOFTWARE' => 'Apache', 700 'SERVER_PORT' => '80', 701 'REQUEST_METHOD' => 'GET', 702 'REQUEST_URI' => '/pluginfile.php/3854/whatever/content/1/swf.html?file=video_.swf', 703 'SCRIPT_NAME' => '/pluginfile.php', 704 'PATH_INFO' => '/3854/whatever/content/1/swf.html', 705 ), 0, '/3854/whatever/content/1/swf.html'), 706 array(array( 707 'SERVER_SOFTWARE' => 'Apache', 708 'SERVER_PORT' => '80', 709 'REQUEST_METHOD' => 'GET', 710 'REQUEST_URI' => '/pluginfile.php/3854/whatever/content/1/swf.html?file=video_.swf', 711 'SCRIPT_NAME' => '/pluginfile.php', 712 'PATH_INFO' => '/3854/whatever/content/1/swf.html', 713 ), 1, '/3854/whatever/content/1/swf.html'), 714 // Serving content from a generic activity w/ HTTP GET 'file', still forcing slash arguments (edge case). 715 array(array( 716 'SERVER_SOFTWARE' => 'Apache', 717 'SERVER_PORT' => '80', 718 'REQUEST_METHOD' => 'GET', 719 'REQUEST_URI' => '/pluginfile.php/?file=video_.swf', 720 'SCRIPT_NAME' => '/pluginfile.php', 721 'PATH_INFO' => '/', 722 ), 0, 'video_.swf'), 723 array(array( 724 'SERVER_SOFTWARE' => 'Apache', 725 'SERVER_PORT' => '80', 726 'REQUEST_METHOD' => 'GET', 727 'REQUEST_URI' => '/pluginfile.php/?file=video_.swf', 728 'SCRIPT_NAME' => '/pluginfile.php', 729 'PATH_INFO' => '/', 730 ), 1, 'video_.swf'), 731 // Serving content from a generic activity w/ HTTP GET 'file', w/o forcing slash arguments. 732 array(array( 733 'SERVER_SOFTWARE' => 'Apache', 734 'SERVER_PORT' => '80', 735 'REQUEST_METHOD' => 'GET', 736 'REQUEST_URI' => '/pluginfile.php?file=%2F3854%2Fwhatever%2Fcontent%2F1%2Fswf.html%3Ffile%3Dvideo_.swf', 737 'SCRIPT_NAME' => '/pluginfile.php', 738 ), 0, '/3854/whatever/content/1/swf.html?file=video_.swf'), 739 array(array( 740 'SERVER_SOFTWARE' => 'Apache', 741 'SERVER_PORT' => '80', 742 'REQUEST_METHOD' => 'GET', 743 'REQUEST_URI' => '/pluginfile.php?file=%2F3854%2Fwhatever%2Fcontent%2F1%2Fswf.html%3Ffile%3Dvideo_.swf', 744 'SCRIPT_NAME' => '/pluginfile.php', 745 ), 1, '/3854/whatever/content/1/swf.html?file=video_.swf'), 746 ); 747 } 748 749 /** 750 * Tests for get_file_argument() function. 751 * 752 * @param array $server mockup for $_SERVER. 753 * @param string $cfgslasharguments slasharguments setting. 754 * @param string|false $expected Expected value. 755 * @dataProvider provider_get_file_argument 756 */ 757 public function test_get_file_argument($server, $cfgslasharguments, $expected) { 758 global $CFG; 759 760 // Overwrite the related settings. 761 $currentsetting = $CFG->slasharguments; 762 $CFG->slasharguments = $cfgslasharguments; 763 // Mock global $_SERVER. 764 $currentserver = isset($_SERVER) ? $_SERVER : null; 765 $_SERVER = $server; 766 initialise_fullme(); 767 if ($_SERVER['REQUEST_METHOD'] !== 'GET') { 768 $this->fail('Only HTTP GET mocked request allowed.'); 769 } 770 if (empty($_SERVER['REQUEST_URI'])) { 771 $this->fail('Invalid HTTP GET mocked request.'); 772 } 773 // Mock global $_GET. 774 $currentget = isset($_GET) ? $_GET : null; 775 $_GET = array(); 776 $querystring = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY); 777 if (!empty($querystring)) { 778 $_SERVER['QUERY_STRING'] = $querystring; 779 parse_str($querystring, $_GET); 780 } 781 782 $this->assertEquals($expected, get_file_argument()); 783 784 // Restore the current settings and global values. 785 $CFG->slasharguments = $currentsetting; 786 if (is_null($currentserver)) { 787 unset($_SERVER); 788 } else { 789 $_SERVER = $currentserver; 790 } 791 if (is_null($currentget)) { 792 unset($_GET); 793 } else { 794 $_GET = $currentget; 795 } 796 } 797 798 /** 799 * Tests for extract_draft_file_urls_from_text() function. 800 */ 801 public function test_extract_draft_file_urls_from_text() { 802 global $CFG; 803 804 $url1 = "{$CFG->wwwroot}/draftfile.php/5/user/draft/99999999/test1.jpg"; 805 $url2 = "{$CFG->wwwroot}/draftfile.php/5/user/draft/99999998/test2.jpg"; 806 807 $html = "<p>This is a test.</p><p><img src=\"$url1}\" alt=\"\" role=\"presentation\"></p> 808 <br>Test content.<p></p><p><img src=\"{$url2}\" alt=\"\" width=\"2048\" height=\"1536\" 809 role=\"presentation\" class=\"img-fluid atto_image_button_text-bottom\"><br></p>"; 810 $draftareas = array( 811 array( 812 'urlbase' => 'draftfile.php', 813 'contextid' => '5', 814 'component' => 'user', 815 'filearea' => 'draft', 816 'itemid' => '99999999', 817 'filename' => 'test1.jpg', 818 0 => "{$CFG->wwwroot}/draftfile.php/5/user/draft/99999999/test1.jpg", 819 1 => 'draftfile.php', 820 2 => '5', 821 3 => 'user', 822 4 => 'draft', 823 5 => '99999999', 824 6 => 'test1.jpg' 825 ), 826 array( 827 'urlbase' => 'draftfile.php', 828 'contextid' => '5', 829 'component' => 'user', 830 'filearea' => 'draft', 831 'itemid' => '99999998', 832 'filename' => 'test2.jpg', 833 0 => "{$CFG->wwwroot}/draftfile.php/5/user/draft/99999998/test2.jpg", 834 1 => 'draftfile.php', 835 2 => '5', 836 3 => 'user', 837 4 => 'draft', 838 5 => '99999998', 839 6 => 'test2.jpg' 840 ) 841 ); 842 $extracteddraftareas = extract_draft_file_urls_from_text($html, false, 5, 'user', 'draft'); 843 $this->assertEquals($draftareas, $extracteddraftareas); 844 } 845 846 public function test_print_password_policy() { 847 $this->resetAfterTest(true); 848 global $CFG; 849 850 $policydisabled = ''; 851 852 // Set password policy to disabled. 853 $CFG->passwordpolicy = false; 854 855 // Check for empty response. 856 $this->assertEquals($policydisabled, print_password_policy()); 857 858 // Now set the policy to enabled with every control disabled. 859 $CFG->passwordpolicy = true; 860 $CFG->minpasswordlength = 0; 861 $CFG->minpassworddigits = 0; 862 $CFG->minpasswordlower = 0; 863 $CFG->minpasswordupper = 0; 864 $CFG->minpasswordnonalphanum = 0; 865 $CFG->maxconsecutiveidentchars = 0; 866 867 // Check for empty response. 868 $this->assertEquals($policydisabled, print_password_policy()); 869 870 // Now enable some controls, and check that the policy responds with policy text. 871 $CFG->minpasswordlength = 8; 872 $CFG->minpassworddigits = 1; 873 $CFG->minpasswordlower = 1; 874 $CFG->minpasswordupper = 1; 875 $CFG->minpasswordnonalphanum = 1; 876 $CFG->maxconsecutiveidentchars = 1; 877 878 $this->assertNotEquals($policydisabled, print_password_policy()); 879 } 880 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body