Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/markup/__tests__/PhutilMarkupTestCase.php
- This file was added.
| <?php | |||||
| final class PhutilMarkupTestCase extends PhutilTestCase { | |||||
| public function testTagDefaults() { | |||||
| $this->assertEqual( | |||||
| (string)phutil_tag('br'), | |||||
| (string)phutil_tag('br', array())); | |||||
| $this->assertEqual( | |||||
| (string)phutil_tag('br', array()), | |||||
| (string)phutil_tag('br', array(), null)); | |||||
| } | |||||
| public function testTagEmpty() { | |||||
| $this->assertEqual( | |||||
| '<br />', | |||||
| (string)phutil_tag('br', array(), null)); | |||||
| $this->assertEqual( | |||||
| '<div></div>', | |||||
| (string)phutil_tag('div', array(), null)); | |||||
| $this->assertEqual( | |||||
| '<div></div>', | |||||
| (string)phutil_tag('div', array(), '')); | |||||
| } | |||||
| public function testTagBasics() { | |||||
| $this->assertEqual( | |||||
| '<br />', | |||||
| (string)phutil_tag('br')); | |||||
| $this->assertEqual( | |||||
| '<div>y</div>', | |||||
| (string)phutil_tag('div', array(), 'y')); | |||||
| } | |||||
| public function testTagAttributes() { | |||||
| $this->assertEqual( | |||||
| '<div u="v">y</div>', | |||||
| (string)phutil_tag('div', array('u' => 'v'), 'y')); | |||||
| $this->assertEqual( | |||||
| '<br u="v" />', | |||||
| (string)phutil_tag('br', array('u' => 'v'))); | |||||
| } | |||||
| public function testTagEscapes() { | |||||
| $this->assertEqual( | |||||
| '<br u="<" />', | |||||
| (string)phutil_tag('br', array('u' => '<'))); | |||||
| $this->assertEqual( | |||||
| '<div><br /></div>', | |||||
| (string)phutil_tag('div', array(), phutil_tag('br'))); | |||||
| } | |||||
| public function testTagNullAttribute() { | |||||
| $this->assertEqual( | |||||
| '<br />', | |||||
| (string)phutil_tag('br', array('y' => null))); | |||||
| } | |||||
| public function testTagJavascriptProtocolRejection() { | |||||
| $hrefs = array( | |||||
| 'javascript:alert(1)' => true, | |||||
| 'JAVASCRIPT:alert(2)' => true, | |||||
| // NOTE: When interpreted as a URI, this is dropped because of leading | |||||
| // whitespace. | |||||
| ' javascript:alert(3)' => array(true, false), | |||||
| '/' => false, | |||||
| '/path/to/stuff/' => false, | |||||
| '' => false, | |||||
| 'http://example.com/' => false, | |||||
| '#' => false, | |||||
| 'javascript://anything' => true, | |||||
| // Chrome 33 and IE11, at a minimum, treat this as Javascript. | |||||
| "javascript\n:alert(4)" => true, | |||||
| // Opera currently accepts a variety of unicode spaces. This test case | |||||
| // has a smattering of them. | |||||
| "\xE2\x80\x89javascript:" => true, | |||||
| "javascript\xE2\x80\x89:" => true, | |||||
| "\xE2\x80\x84javascript:" => true, | |||||
| "javascript\xE2\x80\x84:" => true, | |||||
| // Because we're aggressive, all of unicode should trigger detection | |||||
| // by default. | |||||
| "\xE2\x98\x83javascript:" => true, | |||||
| "javascript\xE2\x98\x83:" => true, | |||||
| "\xE2\x98\x83javascript\xE2\x98\x83:" => true, | |||||
| // We're aggressive about this, so we'll intentionally raise false | |||||
| // positives in these cases. | |||||
| 'javascript~:alert(5)' => true, | |||||
| '!!!javascript!!!!:alert(6)' => true, | |||||
| // However, we should raise true negatives in these slightly more | |||||
| // reasonable cases. | |||||
| 'javascript/:docs.html' => false, | |||||
| 'javascripts:x.png' => false, | |||||
| 'COOLjavascript:page' => false, | |||||
| '/javascript:alert(1)' => false, | |||||
| ); | |||||
| foreach (array(true, false) as $use_uri) { | |||||
| foreach ($hrefs as $href => $expect) { | |||||
| if (is_array($expect)) { | |||||
| $expect = ($use_uri ? $expect[1] : $expect[0]); | |||||
| } | |||||
| if ($use_uri) { | |||||
| $href_value = new PhutilURI($href); | |||||
| } else { | |||||
| $href_value = $href; | |||||
| } | |||||
| $caught = null; | |||||
| try { | |||||
| phutil_tag('a', array('href' => $href_value), 'click for candy'); | |||||
| } catch (Exception $ex) { | |||||
| $caught = $ex; | |||||
| } | |||||
| $desc = pht( | |||||
| 'Unexpected result for "%s". <uri = %s, expect exception = %s>', | |||||
| $href, | |||||
| $use_uri ? pht('Yes') : pht('No'), | |||||
| $expect ? pht('Yes') : pht('No')); | |||||
| $this->assertEqual( | |||||
| $expect, | |||||
| $caught instanceof Exception, | |||||
| $desc); | |||||
| } | |||||
| } | |||||
| } | |||||
| public function testURIEscape() { | |||||
| $this->assertEqual( | |||||
| '%2B/%20%3F%23%26%3A%21xyz%25', | |||||
| phutil_escape_uri('+/ ?#&:!xyz%')); | |||||
| } | |||||
| public function testURIPathComponentEscape() { | |||||
| $this->assertEqual( | |||||
| 'a%252Fb', | |||||
| phutil_escape_uri_path_component('a/b')); | |||||
| $str = ''; | |||||
| for ($ii = 0; $ii <= 255; $ii++) { | |||||
| $str .= chr($ii); | |||||
| } | |||||
| $this->assertEqual( | |||||
| $str, | |||||
| phutil_unescape_uri_path_component( | |||||
| rawurldecode( // Simulates webserver. | |||||
| phutil_escape_uri_path_component($str)))); | |||||
| } | |||||
| public function testHsprintf() { | |||||
| $this->assertEqual( | |||||
| '<div><3</div>', | |||||
| (string)hsprintf('<div>%s</div>', '<3')); | |||||
| } | |||||
| public function testAppendHTML() { | |||||
| $html = phutil_tag('hr'); | |||||
| $html->appendHTML(phutil_tag('br'), '<evil>'); | |||||
| $this->assertEqual('<hr /><br /><evil>', $html->getHTMLContent()); | |||||
| } | |||||
| public function testArrayEscaping() { | |||||
| $this->assertEqual( | |||||
| '<div><div></div>', | |||||
| phutil_escape_html( | |||||
| array( | |||||
| hsprintf('<div>'), | |||||
| array( | |||||
| array( | |||||
| '<', | |||||
| array( | |||||
| 'd', | |||||
| array( | |||||
| array( | |||||
| hsprintf('i'), | |||||
| ), | |||||
| 'v', | |||||
| ), | |||||
| ), | |||||
| array( | |||||
| array( | |||||
| '>', | |||||
| ), | |||||
| ), | |||||
| ), | |||||
| ), | |||||
| hsprintf('</div>'), | |||||
| ))); | |||||
| $this->assertEqual( | |||||
| '<div><br /><hr /><wbr /></div>', | |||||
| phutil_tag( | |||||
| 'div', | |||||
| array(), | |||||
| array( | |||||
| array( | |||||
| array( | |||||
| phutil_tag('br'), | |||||
| array( | |||||
| phutil_tag('hr'), | |||||
| ), | |||||
| phutil_tag('wbr'), | |||||
| ), | |||||
| ), | |||||
| ))->getHTMLContent()); | |||||
| } | |||||
| } | |||||