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