| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 | <?php/** * @file * Pathologic behavior testing. *//** * Tests that Pathologic ain't broke. * * We extend FilterUnitTestCase because it has some nice methods that we also * want to be able to use. * * Note to self: The method to pass bits of text through are fail() or pass(). */class PathologicTestCase extends DrupalWebTestCase {  public static function getInfo() {    return array(      'name' => 'Pathologic path filtering',      'description' => 'Test Pathologic’s path translation and conversion.',      'group' => 'Filter',    );  }  function setUp() {    parent::setUp('pathologic');  }  function testPathologic() {    // Start by testing our function to build protocol-relative URLs    $this->assertEqual(      _pathologic_url_to_protocol_relative('http://example.com/foo/bar'),      '//example.com/foo/bar',      t('Protocol-relative URL creation with http:// URL')    );    $this->assertEqual(      _pathologic_url_to_protocol_relative('https://example.org/baz'),      '//example.org/baz',      t('Protocol-relative URL creation with https:// URL')    );    // Build a phony filter    $filter = new stdClass;    $filter->callback = '_pathologic';    $filter->settings = array(      'protocol_style' => 'full',      'local_paths' => '',    );    $filter->format = 0;    // Build some paths to check against    $test_paths = array(      'foo' => array(        'path' => 'foo',        'opts' => array()      ),      'foo/bar' => array(        'path' => 'foo/bar',        'opts' => array()      ),      'foo/bar?baz' => array(        'path' => 'foo/bar',        'opts' => array('query' => array('baz' => NULL))      ),      'foo/bar?baz=qux' => array(        'path' => 'foo/bar',        'opts' => array('query' => array('baz' => 'qux'))      ),      'foo/bar#baz' => array(        'path' => 'foo/bar',        'opts' => array('fragment' => 'baz'),      ),      'foo/bar?baz=qux&quux=quuux#quuuux' => array(        'path' => 'foo/bar',        'opts' => array(          'query' => array('baz' => 'qux', 'quux' => 'quuux'),          'fragment' => 'quuuux',        ),      ),      'foo%20bar?baz=qux%26quux' => array(        'path' => 'foo bar',        'opts' => array(          'query' => array('baz' => 'qux&quux'),        ),      ),      '/' => array(        'path' => '<front>',        'opts' => array(),      ),    );    // Run tests with clean URLs both enabled and disabled    foreach (array(TRUE, FALSE) as $clean_url) {      variable_set('clean_url', $clean_url);      // Run tests with absoulte filtering enabled and disabled      foreach (array('full', 'proto-rel', 'path') as $protocol_style) {        $filter->settings['protocol_style'] = $protocol_style;        $filter->format++;        $paths = array();        foreach ($test_paths as $path => $args) {          $args['opts']['absolute'] = $protocol_style !== 'path';          $paths[$path] = _pathologic_content_url($args['path'], $args['opts']);          if ($protocol_style === 'proto-rel') {            $paths[$path] = _pathologic_url_to_protocol_relative($paths[$path]);          }        }        $t10ns = array(          '!clean' => $clean_url ? t('Yes') : t('No'),          '!ps' => $protocol_style,        );        $this->assertEqual(          _pathologic_filter('<a href="foo"><img src="foo/bar" /></a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="' . $paths['foo'] . '"><img src="' . $paths['foo/bar'] . '" /></a>',          t('Simple paths. Clean URLs: !clean; protocol style: !ps.', $t10ns)        );        $this->assertEqual(          _pathologic_filter('<form action="foo/bar?baz"><IMG LONGDESC="foo/bar?baz=qux" /></a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<form action="' . $paths['foo/bar?baz'] . '"><IMG LONGDESC="' . $paths['foo/bar?baz=qux'] . '" /></a>',          t('Paths with query string. Clean URLs: !clean; protocol style: !ps.', $t10ns)        );        $this->assertEqual(          _pathologic_filter('<a href="foo/bar#baz">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="' . $paths['foo/bar#baz'] . '">',          t('Path with fragment. Clean URLs: !clean; protocol style: !ps.', $t10ns)        );        $this->assertEqual(          _pathologic_filter('<a href="#foo">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="#foo">',          t('Fragment-only links. Clean URLs: !clean; protocol style: !ps.', $t10ns)        );        $this->assertEqual(          _pathologic_filter('<a href="foo/bar?baz=qux&quux=quuux#quuuux">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="' . $paths['foo/bar?baz=qux&quux=quuux#quuuux'] . '">',          t('Path with query string and fragment. Clean URLs: !clean; protocol style: !ps.', $t10ns)        );        $this->assertEqual(          _pathologic_filter('<a href="foo%20bar?baz=qux%26quux">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="' . $paths['foo%20bar?baz=qux%26quux'] . '">',          t('Path with URL encoded parts')        );        $this->assertEqual(          _pathologic_filter('<a href="/"></a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),          '<a href="' . $paths['/'] . '"></a>',          t('Path with just slash. Clean URLs: !clean; protocol style: !ps', $t10ns)        );      }    }    global $base_path;    $this->assertEqual(      _pathologic_filter('<a href="' . $base_path . 'foo">bar</a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => FALSE)) .'">bar</a>',      t('Paths beginning with $base_path (like WYSIWYG editors like to make)')    );    global $base_url;    $this->assertEqual(      _pathologic_filter('<a href="' . $base_url . '/foo">bar</a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => FALSE)) .'">bar</a>',      t('Paths beginning with $base_url')    );    // @see http://drupal.org/node/1617944    $this->assertEqual(      _pathologic_filter('<a href="//example.com/foo">bar</a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="//example.com/foo">bar</a>',      t('Off-site schemeless URLs (//example.com/foo) ignored')    );    // Test internal: and all base paths    $filter->settings = array(      'protocol_style' => 'full',      'local_paths' => "http://example.com/qux\nhttp://example.org\n/bananas",    );    $filter->format++;    // @see https://drupal.org/node/2030789    $this->assertEqual(      _pathologic_filter('<a href="//example.org/foo">bar</a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => TRUE)) . '">bar</a>',      t('On-site schemeless URLs processed')    );    $this->assertEqual(      _pathologic_filter('<a href="internal:foo">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => TRUE)) . '">',      t('Path Filter compatibility (internal:)')    );    $this->assertEqual(      _pathologic_filter('<a href="files:image.jpeg">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url(file_create_url('public://image.jpeg'), array('absolute' => TRUE, 'is_file' => TRUE)) . '">',      t('Path Filter compatibility (files:)')    );    $this->assertEqual(      _pathologic_filter('<a href="http://example.com/qux/foo"><img src="http://example.org/bar.jpeg" longdesc="/bananas/baz" /></a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => TRUE)) . '"><img src="' . _pathologic_content_url('bar.jpeg', array('absolute' => TRUE)) . '" longdesc="' . _pathologic_content_url('baz', array('absolute' => TRUE)) . '" /></a>',      t('"All base paths for this site" functionality')    );    $this->assertEqual(      _pathologic_filter('<a href="webcal:foo">bar</a>', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="webcal:foo">bar</a>',      t('URLs with likely protocols are ignored')    );    // Test hook_pathologic_alter() implementation.    $this->assertEqual(      _pathologic_filter('<a href="foo?test=add_foo_qpart">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="' . _pathologic_content_url('foo', array('absolute' => TRUE, 'query' => array('test' => 'add_foo_qpart', 'foo' => 'bar'))) . '">',      t('hook_pathologic_alter(): Alter $url_params')    );    $this->assertEqual(      _pathologic_filter('<a href="bar?test=use_original">', $filter, NULL, LANGUAGE_NONE, NULL, NULL),      '<a href="bar?test=use_original">',      t('hook_pathologic_alter(): Passthrough with use_original option')    );    // Test paths to existing files when clean URLs are disabled.    // @see http://drupal.org/node/1672430    variable_set('clean_url', FALSE);    $filtered_tag = _pathologic_filter('<img src="misc/druplicon.png" />', $filter, NULL, LANGUAGE_NONE, NULL, NULL);    $this->assertTrue(      strpos($filtered_tag, 'q=') === FALSE,      t('Paths to files don\'t have ?q= when clean URLs are off')    );  }}/** * Wrapper around url() which does HTML entity decoding and encoding. * * Since Pathologic works with paths in content, it needs to decode paths which * have been HTML-encoded, and re-encode them when done. This is a wrapper * around url() which does the same thing so that we can expect the results * from it and from Pathologic to still match in our tests. * * @see url() * @see http://drupal.org/node/1672932 * @see http://www.w3.org/TR/xhtml1/guidelines.html#C_12 */function _pathologic_content_url($path, $options) {  // If we should pretend this is a path to a file, temporarily enable clean  // URLs if necessary.  // @see _pathologic_replace()  // @see http://drupal.org/node/1672430  if (!empty($options['is_file'])) {    $options['orig_clean_url'] = !empty($GLOBALS['conf']['clean_url']);    if (!$options['orig_clean_url']) {      $GLOBALS['conf']['clean_url'] = TRUE;    }  }  $url = check_plain(url(htmlspecialchars_decode($path), $options));  if (!empty($options['is_file']) && !$options['orig_clean_url']) {    $GLOBALS['conf']['clean_url'] = FALSE;  }  return $url;}/** * Implements hook_pathologic_alter(), for testing that functionality. */function pathologic_pathologic_alter(&$url_params, $parts, $settings) {  if (is_array($parts['qparts']) && isset($parts['qparts']['test'])) {    if ($parts['qparts']['test'] === 'add_foo_qpart') {      // Add a "foo" query part      if (empty($url_params['options']['query'])) {        $url_params['options']['query'] = array();      }      $url_params['options']['query']['foo'] = 'bar';    }    elseif ($parts['qparts']['test'] === 'use_original') {      $url_params['options']['use_original'] = TRUE;    }  }}
 |