Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / pathologic / src / Tests / PathologicTest.php
1 <?php
2
3 namespace Drupal\pathologic\Tests;
4
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\simpletest\WebTestBase;
7 use Drupal\pathologic\Plugin\Filter\FilterPathologic;
8 use Drupal\Core\Language\Language;
9 use Drupal\Core\Url;
10
11 /**
12  * Tests Pathologic functionality.
13  *
14  * @group filter
15  */
16 class PathologicTest extends WebTestBase {
17
18   public static $modules = ['filter', 'pathologic', 'pathologic_test'];
19
20   function testPathologic() {
21     global $script_path;
22
23     // Start by testing our function to build protocol-relative URLs
24     $this->assertEqual(
25       _pathologic_url_to_protocol_relative('http://example.com/foo/bar'),
26       '//example.com/foo/bar',
27       t('Protocol-relative URL creation with http:// URL')
28     );
29     $this->assertEqual(
30       _pathologic_url_to_protocol_relative('https://example.org/baz'),
31       '//example.org/baz',
32       t('Protocol-relative URL creation with https:// URL')
33     );
34
35     // Build some paths to check against
36     $test_paths =[
37       'foo' => [
38         'path' => 'foo',
39         'opts' => []
40       ],
41       'foo/bar' => [
42         'path' => 'foo/bar',
43         'opts' => []
44       ],
45       'foo/bar?baz' => [
46         'path' => 'foo/bar',
47         'opts' => ['query' => ['baz' => NULL]]
48       ],
49       'foo/bar?baz=qux' => [
50         'path' => 'foo/bar',
51         'opts' => ['query' => ['baz' => 'qux']]
52       ],
53       'foo/bar#baz' => [
54         'path' => 'foo/bar',
55         'opts' => ['fragment' => 'baz'],
56       ],
57       'foo/bar?baz=qux&amp;quux=quuux#quuuux' => [
58         'path' => 'foo/bar',
59         'opts' => [
60           'query' => ['baz' => 'qux', 'quux' => 'quuux'],
61           'fragment' => 'quuuux',
62         ],
63       ],
64       'foo%20bar?baz=qux%26quux' => [
65         'path' => 'foo bar',
66         'opts' => [
67           'query' => ['baz' => 'qux&quux'],
68         ],
69       ],
70       '/' => [
71         'path' => '<front>',
72         'opts' => [],
73       ],
74     ];
75
76     foreach (['full', 'proto-rel', 'path'] as $protocol_style) {
77       $format_id = _pathologic_build_format(['settings_source' => 'local', 'local_settings' => ['protocol_style' => $protocol_style]]);
78       $paths = [];
79       foreach ($test_paths as $path => $args) {
80         $args['opts']['absolute'] = $protocol_style !== 'path';
81         $paths[$path] = _pathologic_content_url($args['path'], $args['opts']);
82         if ($protocol_style === 'proto-rel') {
83           $paths[$path] = _pathologic_url_to_protocol_relative($paths[$path]);
84         }
85       }
86       $t10ns = [
87         '@clean' => empty($script_path) ? t('Yes') : t('No'),
88         '@ps' => $protocol_style,
89       ];
90
91       $this->assertEqual(
92         check_markup('<a href="foo"><img src="foo/bar" /></a>', $format_id),
93         '<a href="' . $paths['foo'] . '"><img src="' . $paths['foo/bar'] . '" /></a>',
94         t('Simple paths. Clean URLs: @clean; protocol style: @ps.', $t10ns)
95       );
96       $this->assertEqual(
97         check_markup('<a href="index.php?q=foo"></a><a href="index.php?q=foo/bar&baz=qux"></a>', $format_id),
98         '<a href="' . $paths['foo'] . '"></a><a href="' . $paths['foo/bar?baz=qux'] . '"></a>',
99         t('D7 and earlier-style non-clean URLs. Clean URLs: @clean; protocol style: @ps.', $t10ns)
100       );
101       $this->assertEqual(
102         check_markup('<a href="index.php/foo"></a><a href="index.php/foo/bar?baz=qux"></a>', $format_id),
103         '<a href="' . $paths['foo'] . '"></a><a href="' . $paths['foo/bar?baz=qux'] . '"></a>',
104         t('D8-style non-clean URLs. Clean URLs: @clean; protocol style: @ps.', $t10ns)
105       );
106       $this->assertEqual(
107         check_markup('<form action="foo/bar?baz"><IMG LONGDESC="foo/bar?baz=qux" /></a>', $format_id),
108         '<form action="' . $paths['foo/bar?baz'] . '"><IMG LONGDESC="' . $paths['foo/bar?baz=qux'] . '" /></a>',
109         t('Paths with query string. Clean URLs: @clean; protocol style: @ps.', $t10ns)
110       );
111       $this->assertEqual(
112         check_markup('<a href="foo/bar#baz">', $format_id),
113         '<a href="' . $paths['foo/bar#baz'] . '">',
114         t('Path with fragment. Clean URLs: @clean; protocol style: @ps.', $t10ns)
115       );
116       $this->assertEqual(
117         check_markup('<a href="#foo">', $format_id),
118         '<a href="#foo">',
119         t('Fragment-only href. Clean URLs: @clean; protocol style: @ps.', $t10ns)
120       );
121       // @see https://drupal.org/node/2208223
122       $this->assertEqual(
123         check_markup('<a href="#">', $format_id),
124         '<a href="#">',
125         t('Hash-only href. Clean URLs: @clean; protocol style: @ps.', $t10ns)
126       );
127       $this->assertEqual(
128         check_markup('<a href="foo/bar?baz=qux&amp;quux=quuux#quuuux">', $format_id),
129         '<a href="' . $paths['foo/bar?baz=qux&amp;quux=quuux#quuuux'] . '">',
130         t('Path with query string and fragment. Clean URLs: @clean; protocol style: @ps.', $t10ns)
131       );
132       $this->assertEqual(
133         check_markup('<a href="foo%20bar?baz=qux%26quux">', $format_id),
134         '<a href="' . $paths['foo%20bar?baz=qux%26quux'] . '">',
135         t('Path with URL encoded parts. Clean URLs: @clean; protocol style: @ps.', $t10ns)
136       );
137       $this->assertEqual(
138         check_markup('<a href="/"></a>', $format_id),
139         '<a href="' . $paths['/'] . '"></a>',
140         t('Path with just slash. Clean URLs: @clean; protocol style: @ps', $t10ns)
141       );
142     }
143
144     global $base_path;
145     $this->assertEqual(
146       check_markup('<a href="' . $base_path . 'foo">bar</a>', $format_id),
147       '<a href="' . _pathologic_content_url('foo', ['absolute' => FALSE]) .'">bar</a>',
148       t('Paths beginning with $base_path (like WYSIWYG editors like to make)')
149     );
150     global $base_url;
151     $this->assertEqual(
152       check_markup('<a href="' . $base_url . '/foo">bar</a>', $format_id),
153       '<a href="' . _pathologic_content_url('foo', ['absolute' => FALSE]) .'">bar</a>',
154       t('Paths beginning with $base_url')
155     );
156
157     // @see http://drupal.org/node/1617944
158     $this->assertEqual(
159       check_markup('<a href="//example.com/foo">bar</a>', $format_id),
160       '<a href="//example.com/foo">bar</a>',
161       t('Off-site schemeless URLs (//example.com/foo) ignored')
162     );
163
164     // Test internal: and all base paths
165     $format_id = _pathologic_build_format([
166       'settings_source' => 'local',
167       'local_settings' => [
168         'local_paths' => "http://example.com/qux\nhttp://example.org\n/bananas",
169         'protocol_style' => 'full',
170       ],
171     ]);
172
173     // @see https://drupal.org/node/2030789
174     $this->assertEqual(
175       check_markup('<a href="//example.org/foo">bar</a>', $format_id),
176       '<a href="' . _pathologic_content_url('foo', ['absolute' => TRUE]) . '">bar</a>',
177       t('On-site schemeless URLs processed')
178     );
179     $this->assertEqual(
180       check_markup('<a href="internal:foo">', $format_id),
181       '<a href="' . _pathologic_content_url('foo', ['absolute' => TRUE]) . '">',
182       t('Path Filter compatibility (internal:)')
183     );
184     $this->assertEqual(
185       check_markup('<a href="files:image.jpeg">look</a>', $format_id),
186       '<a href="' . _pathologic_content_url(file_create_url(file_default_scheme() . '://image.jpeg'), ['absolute' => TRUE]) . '">look</a>',
187       t('Path Filter compatibility (files:)')
188     );
189     $this->assertEqual(
190       check_markup('<a href="http://example.com/qux/foo"><img src="http://example.org/bar.jpeg" longdesc="/bananas/baz" /></a>', $format_id),
191       '<a href="' . _pathologic_content_url('foo', ['absolute' => TRUE]) . '"><img src="' . _pathologic_content_url('bar.jpeg', ['absolute' => TRUE]) . '" longdesc="' . _pathologic_content_url('baz', ['absolute' => TRUE]) . '" /></a>',
192       t('"All base paths for this site" functionality')
193     );
194     $this->assertEqual(
195       check_markup('<a href="webcal:foo">bar</a>', $format_id),
196       '<a href="webcal:foo">bar</a>',
197       t('URLs with likely protocols are ignored')
198     );
199     // Test hook_pathologic_alter() implementation.
200     $this->assertEqual(
201       check_markup('<a href="foo?test=add_foo_qpart">', $format_id),
202       '<a href="' . _pathologic_content_url('foo', ['absolute' => TRUE, 'query' => ['test' => 'add_foo_qpart', 'foo' => 'bar']]) . '">',
203       t('hook_pathologic_alter(): Alter $url_params')
204     );
205     $this->assertEqual(
206       check_markup('<a href="bar?test=use_original">', $format_id),
207       '<a href="bar?test=use_original">',
208       t('hook_pathologic_alter(): Passthrough with use_original option')
209     );
210
211     // Test paths to existing files when clean URLs are disabled.
212     // @see http://drupal.org/node/1672430
213     $script_path = '';
214     $filtered_tag = check_markup('<img src="misc/druplicon.png" />', $format_id);
215     $this->assertTrue(
216       strpos($filtered_tag, 'q=') === FALSE,
217       t('Paths to files don\'t have ?q= when clean URLs are off')
218     );
219
220     $format_id = _pathologic_build_format([
221       'settings_source' => 'global',
222       'local_settings' => [
223         'protocol_style' => 'rel',
224       ],
225     ]);
226     $this->config('pathologic.settings')
227       ->set('protocol_style', 'proto-rel')
228       ->set('local_paths', 'http://example.com/')
229       ->save();
230     $this->assertEqual(
231       check_markup('<img src="http://example.com/foo.jpeg" />', $format_id),
232       '<img src="' . _pathologic_url_to_protocol_relative(_pathologic_content_url('foo.jpeg', ['absolute' => TRUE])) . '" />',
233       t('Use global settings when so configured on the format')
234     );
235
236     // Test really broken URLs.
237     // @see https://www.drupal.org/node/2602312
238     $original = '<a href="/Epic:failure">foo</a>';
239     $message = t('Fails sensibly when \Drupal\Core\Url::fromUri() throws exception');
240     try {
241       $filtered = check_markup($original, $format_id);
242       $this->assertEqual(
243         $original,
244         $filtered,
245         $message
246       );
247     }
248     catch (\Exception $e) {
249       $this->fail($message);
250     }
251
252   }
253
254 }
255
256 /**
257  * Wrapper around url() which does HTML entity decoding and encoding.
258  *
259  * Since Pathologic works with paths in content, it needs to decode paths which
260  * have been HTML-encoded, and re-encode them when done. This is a wrapper
261  * around url() which does the same thing so that we can expect the results
262  * from it and from Pathologic to still match in our tests.
263  *
264  * @see url()
265  * @see http://drupal.org/node/1672932
266  * @see http://www.w3.org/TR/xhtml1/guidelines.html#C_12
267  */
268 function _pathologic_content_url($path, $options) {
269   // If we should pretend this is a path to a file, make url() behave like clean
270   // URLs are enabled.
271   // @see _pathologic_replace()
272   // @see http://drupal.org/node/1672430
273   if (!empty($options['is_file'])) {
274     $options['script_path'] = '';
275   }
276
277   if (parse_url($path, PHP_URL_SCHEME) === NULL) {
278     if ($path == '<front>') {
279       return SafeMarkup::checkPlain(Url::fromRoute('<front>', [], $options)->toString());
280     }
281     $path = 'base://' . $path;
282   }
283   return SafeMarkup::checkPlain(Url::fromUri(htmlspecialchars_decode($path), $options)->toString());
284 }
285
286
287 /**
288  * Build a text format with Pathologic configured a certain way.
289  *
290  * @param $settings
291  *   An array of settings for the Pathologic instance on the format.
292  * @return
293  *   A format machine name (consisting of random characters) for the format.
294  */
295 function _pathologic_build_format($settings) {
296   $format_id = user_password();
297   $format = entity_create('filter_format', [
298     'format' => $format_id,
299     'name' => $format_id,
300   ]);
301   $format->setFilterConfig('filter_pathologic', [
302     'status' => 1,
303     'settings' => $settings,
304   ]);
305   $format->save();
306   return $format_id;
307 }