danielebarchiesi@0
|
1 <?php
|
danielebarchiesi@0
|
2
|
danielebarchiesi@0
|
3 /**
|
danielebarchiesi@0
|
4 * @file
|
danielebarchiesi@0
|
5 * Tests for filter.module.
|
danielebarchiesi@0
|
6 */
|
danielebarchiesi@0
|
7
|
danielebarchiesi@0
|
8 /**
|
danielebarchiesi@0
|
9 * Tests for text format and filter CRUD operations.
|
danielebarchiesi@0
|
10 */
|
danielebarchiesi@0
|
11 class FilterCRUDTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
12 public static function getInfo() {
|
danielebarchiesi@0
|
13 return array(
|
danielebarchiesi@0
|
14 'name' => 'Filter CRUD operations',
|
danielebarchiesi@0
|
15 'description' => 'Test creation, loading, updating, deleting of text formats and filters.',
|
danielebarchiesi@0
|
16 'group' => 'Filter',
|
danielebarchiesi@0
|
17 );
|
danielebarchiesi@0
|
18 }
|
danielebarchiesi@0
|
19
|
danielebarchiesi@0
|
20 function setUp() {
|
danielebarchiesi@0
|
21 parent::setUp('filter_test');
|
danielebarchiesi@0
|
22 }
|
danielebarchiesi@0
|
23
|
danielebarchiesi@0
|
24 /**
|
danielebarchiesi@0
|
25 * Tests CRUD operations for text formats and filters.
|
danielebarchiesi@0
|
26 */
|
danielebarchiesi@0
|
27 function testTextFormatCRUD() {
|
danielebarchiesi@0
|
28 // Add a text format with minimum data only.
|
danielebarchiesi@0
|
29 $format = new stdClass();
|
danielebarchiesi@0
|
30 $format->format = 'empty_format';
|
danielebarchiesi@0
|
31 $format->name = 'Empty format';
|
danielebarchiesi@0
|
32 filter_format_save($format);
|
danielebarchiesi@0
|
33 $this->verifyTextFormat($format);
|
danielebarchiesi@0
|
34 $this->verifyFilters($format);
|
danielebarchiesi@0
|
35
|
danielebarchiesi@0
|
36 // Add another text format specifying all possible properties.
|
danielebarchiesi@0
|
37 $format = new stdClass();
|
danielebarchiesi@0
|
38 $format->format = 'custom_format';
|
danielebarchiesi@0
|
39 $format->name = 'Custom format';
|
danielebarchiesi@0
|
40 $format->filters = array(
|
danielebarchiesi@0
|
41 'filter_url' => array(
|
danielebarchiesi@0
|
42 'status' => 1,
|
danielebarchiesi@0
|
43 'settings' => array(
|
danielebarchiesi@0
|
44 'filter_url_length' => 30,
|
danielebarchiesi@0
|
45 ),
|
danielebarchiesi@0
|
46 ),
|
danielebarchiesi@0
|
47 );
|
danielebarchiesi@0
|
48 filter_format_save($format);
|
danielebarchiesi@0
|
49 $this->verifyTextFormat($format);
|
danielebarchiesi@0
|
50 $this->verifyFilters($format);
|
danielebarchiesi@0
|
51
|
danielebarchiesi@0
|
52 // Alter some text format properties and save again.
|
danielebarchiesi@0
|
53 $format->name = 'Altered format';
|
danielebarchiesi@0
|
54 $format->filters['filter_url']['status'] = 0;
|
danielebarchiesi@0
|
55 $format->filters['filter_autop']['status'] = 1;
|
danielebarchiesi@0
|
56 filter_format_save($format);
|
danielebarchiesi@0
|
57 $this->verifyTextFormat($format);
|
danielebarchiesi@0
|
58 $this->verifyFilters($format);
|
danielebarchiesi@0
|
59
|
danielebarchiesi@0
|
60 // Add a uncacheable filter and save again.
|
danielebarchiesi@0
|
61 $format->filters['filter_test_uncacheable']['status'] = 1;
|
danielebarchiesi@0
|
62 filter_format_save($format);
|
danielebarchiesi@0
|
63 $this->verifyTextFormat($format);
|
danielebarchiesi@0
|
64 $this->verifyFilters($format);
|
danielebarchiesi@0
|
65
|
danielebarchiesi@0
|
66 // Disable the text format.
|
danielebarchiesi@0
|
67 filter_format_disable($format);
|
danielebarchiesi@0
|
68
|
danielebarchiesi@0
|
69 $db_format = db_query("SELECT * FROM {filter_format} WHERE format = :format", array(':format' => $format->format))->fetchObject();
|
danielebarchiesi@0
|
70 $this->assertFalse($db_format->status, 'Database: Disabled text format is marked as disabled.');
|
danielebarchiesi@0
|
71 $formats = filter_formats();
|
danielebarchiesi@0
|
72 $this->assertTrue(!isset($formats[$format->format]), 'filter_formats: Disabled text format no longer exists.');
|
danielebarchiesi@0
|
73 }
|
danielebarchiesi@0
|
74
|
danielebarchiesi@0
|
75 /**
|
danielebarchiesi@0
|
76 * Verifies that a text format is properly stored.
|
danielebarchiesi@0
|
77 */
|
danielebarchiesi@0
|
78 function verifyTextFormat($format) {
|
danielebarchiesi@0
|
79 $t_args = array('%format' => $format->name);
|
danielebarchiesi@0
|
80 // Verify text format database record.
|
danielebarchiesi@0
|
81 $db_format = db_select('filter_format', 'ff')
|
danielebarchiesi@0
|
82 ->fields('ff')
|
danielebarchiesi@0
|
83 ->condition('format', $format->format)
|
danielebarchiesi@0
|
84 ->execute()
|
danielebarchiesi@0
|
85 ->fetchObject();
|
danielebarchiesi@0
|
86 $this->assertEqual($db_format->format, $format->format, format_string('Database: Proper format id for text format %format.', $t_args));
|
danielebarchiesi@0
|
87 $this->assertEqual($db_format->name, $format->name, format_string('Database: Proper title for text format %format.', $t_args));
|
danielebarchiesi@0
|
88 $this->assertEqual($db_format->cache, $format->cache, format_string('Database: Proper cache indicator for text format %format.', $t_args));
|
danielebarchiesi@0
|
89 $this->assertEqual($db_format->weight, $format->weight, format_string('Database: Proper weight for text format %format.', $t_args));
|
danielebarchiesi@0
|
90
|
danielebarchiesi@0
|
91 // Verify filter_format_load().
|
danielebarchiesi@0
|
92 $filter_format = filter_format_load($format->format);
|
danielebarchiesi@0
|
93 $this->assertEqual($filter_format->format, $format->format, format_string('filter_format_load: Proper format id for text format %format.', $t_args));
|
danielebarchiesi@0
|
94 $this->assertEqual($filter_format->name, $format->name, format_string('filter_format_load: Proper title for text format %format.', $t_args));
|
danielebarchiesi@0
|
95 $this->assertEqual($filter_format->cache, $format->cache, format_string('filter_format_load: Proper cache indicator for text format %format.', $t_args));
|
danielebarchiesi@0
|
96 $this->assertEqual($filter_format->weight, $format->weight, format_string('filter_format_load: Proper weight for text format %format.', $t_args));
|
danielebarchiesi@0
|
97
|
danielebarchiesi@0
|
98 // Verify the 'cache' text format property according to enabled filters.
|
danielebarchiesi@0
|
99 $filter_info = filter_get_filters();
|
danielebarchiesi@0
|
100 $filters = filter_list_format($filter_format->format);
|
danielebarchiesi@0
|
101 $cacheable = TRUE;
|
danielebarchiesi@0
|
102 foreach ($filters as $name => $filter) {
|
danielebarchiesi@0
|
103 // If this filter is not cacheable, update $cacheable accordingly, so we
|
danielebarchiesi@0
|
104 // can verify $format->cache after iterating over all filters.
|
danielebarchiesi@0
|
105 if ($filter->status && isset($filter_info[$name]['cache']) && !$filter_info[$name]['cache']) {
|
danielebarchiesi@0
|
106 $cacheable = FALSE;
|
danielebarchiesi@0
|
107 break;
|
danielebarchiesi@0
|
108 }
|
danielebarchiesi@0
|
109 }
|
danielebarchiesi@0
|
110 $this->assertEqual($filter_format->cache, $cacheable, 'Text format contains proper cache property.');
|
danielebarchiesi@0
|
111 }
|
danielebarchiesi@0
|
112
|
danielebarchiesi@0
|
113 /**
|
danielebarchiesi@0
|
114 * Verifies that filters are properly stored for a text format.
|
danielebarchiesi@0
|
115 */
|
danielebarchiesi@0
|
116 function verifyFilters($format) {
|
danielebarchiesi@0
|
117 // Verify filter database records.
|
danielebarchiesi@0
|
118 $filters = db_query("SELECT * FROM {filter} WHERE format = :format", array(':format' => $format->format))->fetchAllAssoc('name');
|
danielebarchiesi@0
|
119 $format_filters = $format->filters;
|
danielebarchiesi@0
|
120 foreach ($filters as $name => $filter) {
|
danielebarchiesi@0
|
121 $t_args = array('%format' => $format->name, '%filter' => $name);
|
danielebarchiesi@0
|
122
|
danielebarchiesi@0
|
123 // Verify that filter status is properly stored.
|
danielebarchiesi@0
|
124 $this->assertEqual($filter->status, $format_filters[$name]['status'], format_string('Database: Proper status for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
125
|
danielebarchiesi@0
|
126 // Verify that filter settings were properly stored.
|
danielebarchiesi@0
|
127 $this->assertEqual(unserialize($filter->settings), isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), format_string('Database: Proper filter settings for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
128
|
danielebarchiesi@0
|
129 // Verify that each filter has a module name assigned.
|
danielebarchiesi@0
|
130 $this->assertTrue(!empty($filter->module), format_string('Database: Proper module name for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
131
|
danielebarchiesi@0
|
132 // Remove the filter from the copy of saved $format to check whether all
|
danielebarchiesi@0
|
133 // filters have been processed later.
|
danielebarchiesi@0
|
134 unset($format_filters[$name]);
|
danielebarchiesi@0
|
135 }
|
danielebarchiesi@0
|
136 // Verify that all filters have been processed.
|
danielebarchiesi@0
|
137 $this->assertTrue(empty($format_filters), 'Database contains values for all filters in the saved format.');
|
danielebarchiesi@0
|
138
|
danielebarchiesi@0
|
139 // Verify filter_list_format().
|
danielebarchiesi@0
|
140 $filters = filter_list_format($format->format);
|
danielebarchiesi@0
|
141 $format_filters = $format->filters;
|
danielebarchiesi@0
|
142 foreach ($filters as $name => $filter) {
|
danielebarchiesi@0
|
143 $t_args = array('%format' => $format->name, '%filter' => $name);
|
danielebarchiesi@0
|
144
|
danielebarchiesi@0
|
145 // Verify that filter status is properly stored.
|
danielebarchiesi@0
|
146 $this->assertEqual($filter->status, $format_filters[$name]['status'], format_string('filter_list_format: Proper status for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
147
|
danielebarchiesi@0
|
148 // Verify that filter settings were properly stored.
|
danielebarchiesi@0
|
149 $this->assertEqual($filter->settings, isset($format_filters[$name]['settings']) ? $format_filters[$name]['settings'] : array(), format_string('filter_list_format: Proper filter settings for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
150
|
danielebarchiesi@0
|
151 // Verify that each filter has a module name assigned.
|
danielebarchiesi@0
|
152 $this->assertTrue(!empty($filter->module), format_string('filter_list_format: Proper module name for %filter in text format %format.', $t_args));
|
danielebarchiesi@0
|
153
|
danielebarchiesi@0
|
154 // Remove the filter from the copy of saved $format to check whether all
|
danielebarchiesi@0
|
155 // filters have been processed later.
|
danielebarchiesi@0
|
156 unset($format_filters[$name]);
|
danielebarchiesi@0
|
157 }
|
danielebarchiesi@0
|
158 // Verify that all filters have been processed.
|
danielebarchiesi@0
|
159 $this->assertTrue(empty($format_filters), 'filter_list_format: Loaded filters contain values for all filters in the saved format.');
|
danielebarchiesi@0
|
160 }
|
danielebarchiesi@0
|
161 }
|
danielebarchiesi@0
|
162
|
danielebarchiesi@0
|
163 /**
|
danielebarchiesi@0
|
164 * Tests the administrative functionality of the Filter module.
|
danielebarchiesi@0
|
165 */
|
danielebarchiesi@0
|
166 class FilterAdminTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
167 public static function getInfo() {
|
danielebarchiesi@0
|
168 return array(
|
danielebarchiesi@0
|
169 'name' => 'Filter administration functionality',
|
danielebarchiesi@0
|
170 'description' => 'Thoroughly test the administrative interface of the filter module.',
|
danielebarchiesi@0
|
171 'group' => 'Filter',
|
danielebarchiesi@0
|
172 );
|
danielebarchiesi@0
|
173 }
|
danielebarchiesi@0
|
174
|
danielebarchiesi@0
|
175 function setUp() {
|
danielebarchiesi@0
|
176 parent::setUp();
|
danielebarchiesi@0
|
177
|
danielebarchiesi@0
|
178 // Create users.
|
danielebarchiesi@0
|
179 $filtered_html_format = filter_format_load('filtered_html');
|
danielebarchiesi@0
|
180 $full_html_format = filter_format_load('full_html');
|
danielebarchiesi@0
|
181 $this->admin_user = $this->drupalCreateUser(array(
|
danielebarchiesi@0
|
182 'administer filters',
|
danielebarchiesi@0
|
183 filter_permission_name($filtered_html_format),
|
danielebarchiesi@0
|
184 filter_permission_name($full_html_format),
|
danielebarchiesi@0
|
185 ));
|
danielebarchiesi@0
|
186
|
danielebarchiesi@0
|
187 $this->web_user = $this->drupalCreateUser(array('create page content', 'edit own page content'));
|
danielebarchiesi@0
|
188 $this->drupalLogin($this->admin_user);
|
danielebarchiesi@0
|
189 }
|
danielebarchiesi@0
|
190
|
danielebarchiesi@0
|
191 /**
|
danielebarchiesi@0
|
192 * Tests the format administration functionality.
|
danielebarchiesi@0
|
193 */
|
danielebarchiesi@0
|
194 function testFormatAdmin() {
|
danielebarchiesi@0
|
195 // Add text format.
|
danielebarchiesi@0
|
196 $this->drupalGet('admin/config/content/formats');
|
danielebarchiesi@0
|
197 $this->clickLink('Add text format');
|
danielebarchiesi@0
|
198 $format_id = drupal_strtolower($this->randomName());
|
danielebarchiesi@0
|
199 $name = $this->randomName();
|
danielebarchiesi@0
|
200 $edit = array(
|
danielebarchiesi@0
|
201 'format' => $format_id,
|
danielebarchiesi@0
|
202 'name' => $name,
|
danielebarchiesi@0
|
203 );
|
danielebarchiesi@0
|
204 $this->drupalPost(NULL, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
205
|
danielebarchiesi@0
|
206 // Verify default weight of the text format.
|
danielebarchiesi@0
|
207 $this->drupalGet('admin/config/content/formats');
|
danielebarchiesi@0
|
208 $this->assertFieldByName("formats[$format_id][weight]", 0, 'Text format weight was saved.');
|
danielebarchiesi@0
|
209
|
danielebarchiesi@0
|
210 // Change the weight of the text format.
|
danielebarchiesi@0
|
211 $edit = array(
|
danielebarchiesi@0
|
212 "formats[$format_id][weight]" => 5,
|
danielebarchiesi@0
|
213 );
|
danielebarchiesi@0
|
214 $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
|
danielebarchiesi@0
|
215 $this->assertFieldByName("formats[$format_id][weight]", 5, 'Text format weight was saved.');
|
danielebarchiesi@0
|
216
|
danielebarchiesi@0
|
217 // Edit text format.
|
danielebarchiesi@0
|
218 $this->drupalGet('admin/config/content/formats');
|
danielebarchiesi@0
|
219 $this->assertLinkByHref('admin/config/content/formats/' . $format_id);
|
danielebarchiesi@0
|
220 $this->drupalGet('admin/config/content/formats/' . $format_id);
|
danielebarchiesi@0
|
221 $this->drupalPost(NULL, array(), t('Save configuration'));
|
danielebarchiesi@0
|
222
|
danielebarchiesi@0
|
223 // Verify that the custom weight of the text format has been retained.
|
danielebarchiesi@0
|
224 $this->drupalGet('admin/config/content/formats');
|
danielebarchiesi@0
|
225 $this->assertFieldByName("formats[$format_id][weight]", 5, 'Text format weight was retained.');
|
danielebarchiesi@0
|
226
|
danielebarchiesi@0
|
227 // Disable text format.
|
danielebarchiesi@0
|
228 $this->assertLinkByHref('admin/config/content/formats/' . $format_id . '/disable');
|
danielebarchiesi@0
|
229 $this->drupalGet('admin/config/content/formats/' . $format_id . '/disable');
|
danielebarchiesi@0
|
230 $this->drupalPost(NULL, array(), t('Disable'));
|
danielebarchiesi@0
|
231
|
danielebarchiesi@0
|
232 // Verify that disabled text format no longer exists.
|
danielebarchiesi@0
|
233 $this->drupalGet('admin/config/content/formats/' . $format_id);
|
danielebarchiesi@0
|
234 $this->assertResponse(404, 'Disabled text format no longer exists.');
|
danielebarchiesi@0
|
235
|
danielebarchiesi@0
|
236 // Attempt to create a format of the same machine name as the disabled
|
danielebarchiesi@0
|
237 // format but with a different human readable name.
|
danielebarchiesi@0
|
238 $edit = array(
|
danielebarchiesi@0
|
239 'format' => $format_id,
|
danielebarchiesi@0
|
240 'name' => 'New format',
|
danielebarchiesi@0
|
241 );
|
danielebarchiesi@0
|
242 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
243 $this->assertText('The machine-readable name is already in use. It must be unique.');
|
danielebarchiesi@0
|
244
|
danielebarchiesi@0
|
245 // Attempt to create a format of the same human readable name as the
|
danielebarchiesi@0
|
246 // disabled format but with a different machine name.
|
danielebarchiesi@0
|
247 $edit = array(
|
danielebarchiesi@0
|
248 'format' => 'new_format',
|
danielebarchiesi@0
|
249 'name' => $name,
|
danielebarchiesi@0
|
250 );
|
danielebarchiesi@0
|
251 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
252 $this->assertRaw(t('Text format names must be unique. A format named %name already exists.', array(
|
danielebarchiesi@0
|
253 '%name' => $name,
|
danielebarchiesi@0
|
254 )));
|
danielebarchiesi@0
|
255 }
|
danielebarchiesi@0
|
256
|
danielebarchiesi@0
|
257 /**
|
danielebarchiesi@0
|
258 * Tests filter administration functionality.
|
danielebarchiesi@0
|
259 */
|
danielebarchiesi@0
|
260 function testFilterAdmin() {
|
danielebarchiesi@0
|
261 // URL filter.
|
danielebarchiesi@0
|
262 $first_filter = 'filter_url';
|
danielebarchiesi@0
|
263 // Line filter.
|
danielebarchiesi@0
|
264 $second_filter = 'filter_autop';
|
danielebarchiesi@0
|
265
|
danielebarchiesi@0
|
266 $filtered = 'filtered_html';
|
danielebarchiesi@0
|
267 $full = 'full_html';
|
danielebarchiesi@0
|
268 $plain = 'plain_text';
|
danielebarchiesi@0
|
269
|
danielebarchiesi@0
|
270 // Check that the fallback format exists and cannot be disabled.
|
danielebarchiesi@0
|
271 $this->assertTrue($plain == filter_fallback_format(), 'The fallback format is set to plain text.');
|
danielebarchiesi@0
|
272 $this->drupalGet('admin/config/content/formats');
|
danielebarchiesi@0
|
273 $this->assertNoRaw('admin/config/content/formats/' . $plain . '/disable', 'Disable link for the fallback format not found.');
|
danielebarchiesi@0
|
274 $this->drupalGet('admin/config/content/formats/' . $plain . '/disable');
|
danielebarchiesi@0
|
275 $this->assertResponse(403, 'The fallback format cannot be disabled.');
|
danielebarchiesi@0
|
276
|
danielebarchiesi@0
|
277 // Verify access permissions to Full HTML format.
|
danielebarchiesi@0
|
278 $this->assertTrue(filter_access(filter_format_load($full), $this->admin_user), 'Admin user may use Full HTML.');
|
danielebarchiesi@0
|
279 $this->assertFalse(filter_access(filter_format_load($full), $this->web_user), 'Web user may not use Full HTML.');
|
danielebarchiesi@0
|
280
|
danielebarchiesi@0
|
281 // Add an additional tag.
|
danielebarchiesi@0
|
282 $edit = array();
|
danielebarchiesi@0
|
283 $edit['filters[filter_html][settings][allowed_html]'] = '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <quote>';
|
danielebarchiesi@0
|
284 $this->drupalPost('admin/config/content/formats/' . $filtered, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
285 $this->assertFieldByName('filters[filter_html][settings][allowed_html]', $edit['filters[filter_html][settings][allowed_html]'], 'Allowed HTML tag added.');
|
danielebarchiesi@0
|
286
|
danielebarchiesi@0
|
287 $result = db_query('SELECT * FROM {cache_filter}')->fetchObject();
|
danielebarchiesi@0
|
288 $this->assertFalse($result, 'Cache cleared.');
|
danielebarchiesi@0
|
289
|
danielebarchiesi@0
|
290 $elements = $this->xpath('//select[@name=:first]/following::select[@name=:second]', array(
|
danielebarchiesi@0
|
291 ':first' => 'filters[' . $first_filter . '][weight]',
|
danielebarchiesi@0
|
292 ':second' => 'filters[' . $second_filter . '][weight]',
|
danielebarchiesi@0
|
293 ));
|
danielebarchiesi@0
|
294 $this->assertTrue(!empty($elements), 'Order confirmed in admin interface.');
|
danielebarchiesi@0
|
295
|
danielebarchiesi@0
|
296 // Reorder filters.
|
danielebarchiesi@0
|
297 $edit = array();
|
danielebarchiesi@0
|
298 $edit['filters[' . $second_filter . '][weight]'] = 1;
|
danielebarchiesi@0
|
299 $edit['filters[' . $first_filter . '][weight]'] = 2;
|
danielebarchiesi@0
|
300 $this->drupalPost(NULL, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
301 $this->assertFieldByName('filters[' . $second_filter . '][weight]', 1, 'Order saved successfully.');
|
danielebarchiesi@0
|
302 $this->assertFieldByName('filters[' . $first_filter . '][weight]', 2, 'Order saved successfully.');
|
danielebarchiesi@0
|
303
|
danielebarchiesi@0
|
304 $elements = $this->xpath('//select[@name=:first]/following::select[@name=:second]', array(
|
danielebarchiesi@0
|
305 ':first' => 'filters[' . $second_filter . '][weight]',
|
danielebarchiesi@0
|
306 ':second' => 'filters[' . $first_filter . '][weight]',
|
danielebarchiesi@0
|
307 ));
|
danielebarchiesi@0
|
308 $this->assertTrue(!empty($elements), 'Reorder confirmed in admin interface.');
|
danielebarchiesi@0
|
309
|
danielebarchiesi@0
|
310 $result = db_query('SELECT * FROM {filter} WHERE format = :format ORDER BY weight ASC', array(':format' => $filtered));
|
danielebarchiesi@0
|
311 $filters = array();
|
danielebarchiesi@0
|
312 foreach ($result as $filter) {
|
danielebarchiesi@0
|
313 if ($filter->name == $second_filter || $filter->name == $first_filter) {
|
danielebarchiesi@0
|
314 $filters[] = $filter;
|
danielebarchiesi@0
|
315 }
|
danielebarchiesi@0
|
316 }
|
danielebarchiesi@0
|
317 $this->assertTrue(($filters[0]->name == $second_filter && $filters[1]->name == $first_filter), 'Order confirmed in database.');
|
danielebarchiesi@0
|
318
|
danielebarchiesi@0
|
319 // Add format.
|
danielebarchiesi@0
|
320 $edit = array();
|
danielebarchiesi@0
|
321 $edit['format'] = drupal_strtolower($this->randomName());
|
danielebarchiesi@0
|
322 $edit['name'] = $this->randomName();
|
danielebarchiesi@0
|
323 $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = 1;
|
danielebarchiesi@0
|
324 $edit['filters[' . $second_filter . '][status]'] = TRUE;
|
danielebarchiesi@0
|
325 $edit['filters[' . $first_filter . '][status]'] = TRUE;
|
danielebarchiesi@0
|
326 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
327 $this->assertRaw(t('Added text format %format.', array('%format' => $edit['name'])), 'New filter created.');
|
danielebarchiesi@0
|
328
|
danielebarchiesi@0
|
329 drupal_static_reset('filter_formats');
|
danielebarchiesi@0
|
330 $format = filter_format_load($edit['format']);
|
danielebarchiesi@0
|
331 $this->assertNotNull($format, 'Format found in database.');
|
danielebarchiesi@0
|
332
|
danielebarchiesi@0
|
333 $this->assertFieldByName('roles[' . DRUPAL_AUTHENTICATED_RID . ']', '', 'Role found.');
|
danielebarchiesi@0
|
334 $this->assertFieldByName('filters[' . $second_filter . '][status]', '', 'Line break filter found.');
|
danielebarchiesi@0
|
335 $this->assertFieldByName('filters[' . $first_filter . '][status]', '', 'Url filter found.');
|
danielebarchiesi@0
|
336
|
danielebarchiesi@0
|
337 // Disable new filter.
|
danielebarchiesi@0
|
338 $this->drupalPost('admin/config/content/formats/' . $format->format . '/disable', array(), t('Disable'));
|
danielebarchiesi@0
|
339 $this->assertRaw(t('Disabled text format %format.', array('%format' => $edit['name'])), 'Format successfully disabled.');
|
danielebarchiesi@0
|
340
|
danielebarchiesi@0
|
341 // Allow authenticated users on full HTML.
|
danielebarchiesi@0
|
342 $format = filter_format_load($full);
|
danielebarchiesi@0
|
343 $edit = array();
|
danielebarchiesi@0
|
344 $edit['roles[' . DRUPAL_ANONYMOUS_RID . ']'] = 0;
|
danielebarchiesi@0
|
345 $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = 1;
|
danielebarchiesi@0
|
346 $this->drupalPost('admin/config/content/formats/' . $full, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
347 $this->assertRaw(t('The text format %format has been updated.', array('%format' => $format->name)), 'Full HTML format successfully updated.');
|
danielebarchiesi@0
|
348
|
danielebarchiesi@0
|
349 // Switch user.
|
danielebarchiesi@0
|
350 $this->drupalLogout();
|
danielebarchiesi@0
|
351 $this->drupalLogin($this->web_user);
|
danielebarchiesi@0
|
352
|
danielebarchiesi@0
|
353 $this->drupalGet('node/add/page');
|
danielebarchiesi@0
|
354 $this->assertRaw('<option value="' . $full . '">Full HTML</option>', 'Full HTML filter accessible.');
|
danielebarchiesi@0
|
355
|
danielebarchiesi@0
|
356 // Use filtered HTML and see if it removes tags that are not allowed.
|
danielebarchiesi@0
|
357 $body = '<em>' . $this->randomName() . '</em>';
|
danielebarchiesi@0
|
358 $extra_text = 'text';
|
danielebarchiesi@0
|
359 $text = $body . '<random>' . $extra_text . '</random>';
|
danielebarchiesi@0
|
360
|
danielebarchiesi@0
|
361 $edit = array();
|
danielebarchiesi@0
|
362 $langcode = LANGUAGE_NONE;
|
danielebarchiesi@0
|
363 $edit["title"] = $this->randomName();
|
danielebarchiesi@0
|
364 $edit["body[$langcode][0][value]"] = $text;
|
danielebarchiesi@0
|
365 $edit["body[$langcode][0][format]"] = $filtered;
|
danielebarchiesi@0
|
366 $this->drupalPost('node/add/page', $edit, t('Save'));
|
danielebarchiesi@0
|
367 $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit["title"])), 'Filtered node created.');
|
danielebarchiesi@0
|
368
|
danielebarchiesi@0
|
369 $node = $this->drupalGetNodeByTitle($edit["title"]);
|
danielebarchiesi@0
|
370 $this->assertTrue($node, 'Node found in database.');
|
danielebarchiesi@0
|
371
|
danielebarchiesi@0
|
372 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
373 $this->assertRaw($body . $extra_text, 'Filter removed invalid tag.');
|
danielebarchiesi@0
|
374
|
danielebarchiesi@0
|
375 // Use plain text and see if it escapes all tags, whether allowed or not.
|
danielebarchiesi@0
|
376 $edit = array();
|
danielebarchiesi@0
|
377 $edit["body[$langcode][0][format]"] = $plain;
|
danielebarchiesi@0
|
378 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
379 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
380 $this->assertText(check_plain($text), 'The "Plain text" text format escapes all HTML tags.');
|
danielebarchiesi@0
|
381
|
danielebarchiesi@0
|
382 // Switch user.
|
danielebarchiesi@0
|
383 $this->drupalLogout();
|
danielebarchiesi@0
|
384 $this->drupalLogin($this->admin_user);
|
danielebarchiesi@0
|
385
|
danielebarchiesi@0
|
386 // Clean up.
|
danielebarchiesi@0
|
387 // Allowed tags.
|
danielebarchiesi@0
|
388 $edit = array();
|
danielebarchiesi@0
|
389 $edit['filters[filter_html][settings][allowed_html]'] = '<a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>';
|
danielebarchiesi@0
|
390 $this->drupalPost('admin/config/content/formats/' . $filtered, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
391 $this->assertFieldByName('filters[filter_html][settings][allowed_html]', $edit['filters[filter_html][settings][allowed_html]'], 'Changes reverted.');
|
danielebarchiesi@0
|
392
|
danielebarchiesi@0
|
393 // Full HTML.
|
danielebarchiesi@0
|
394 $edit = array();
|
danielebarchiesi@0
|
395 $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = FALSE;
|
danielebarchiesi@0
|
396 $this->drupalPost('admin/config/content/formats/' . $full, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
397 $this->assertRaw(t('The text format %format has been updated.', array('%format' => $format->name)), 'Full HTML format successfully reverted.');
|
danielebarchiesi@0
|
398 $this->assertFieldByName('roles[' . DRUPAL_AUTHENTICATED_RID . ']', $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'], 'Changes reverted.');
|
danielebarchiesi@0
|
399
|
danielebarchiesi@0
|
400 // Filter order.
|
danielebarchiesi@0
|
401 $edit = array();
|
danielebarchiesi@0
|
402 $edit['filters[' . $second_filter . '][weight]'] = 2;
|
danielebarchiesi@0
|
403 $edit['filters[' . $first_filter . '][weight]'] = 1;
|
danielebarchiesi@0
|
404 $this->drupalPost('admin/config/content/formats/' . $filtered, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
405 $this->assertFieldByName('filters[' . $second_filter . '][weight]', $edit['filters[' . $second_filter . '][weight]'], 'Changes reverted.');
|
danielebarchiesi@0
|
406 $this->assertFieldByName('filters[' . $first_filter . '][weight]', $edit['filters[' . $first_filter . '][weight]'], 'Changes reverted.');
|
danielebarchiesi@0
|
407 }
|
danielebarchiesi@0
|
408
|
danielebarchiesi@0
|
409 /**
|
danielebarchiesi@0
|
410 * Tests the URL filter settings form is properly validated.
|
danielebarchiesi@0
|
411 */
|
danielebarchiesi@0
|
412 function testUrlFilterAdmin() {
|
danielebarchiesi@0
|
413 // The form does not save with an invalid filter URL length.
|
danielebarchiesi@0
|
414 $edit = array(
|
danielebarchiesi@0
|
415 'filters[filter_url][settings][filter_url_length]' => $this->randomName(4),
|
danielebarchiesi@0
|
416 );
|
danielebarchiesi@0
|
417 $this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
418 $this->assertNoRaw(t('The text format %format has been updated.', array('%format' => 'Filtered HTML')));
|
danielebarchiesi@0
|
419 }
|
danielebarchiesi@0
|
420 }
|
danielebarchiesi@0
|
421
|
danielebarchiesi@0
|
422 /**
|
danielebarchiesi@0
|
423 * Tests the filter format access functionality in the Filter module.
|
danielebarchiesi@0
|
424 */
|
danielebarchiesi@0
|
425 class FilterFormatAccessTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
426 /**
|
danielebarchiesi@0
|
427 * A user with administrative permissions.
|
danielebarchiesi@0
|
428 *
|
danielebarchiesi@0
|
429 * @var object
|
danielebarchiesi@0
|
430 */
|
danielebarchiesi@0
|
431 protected $admin_user;
|
danielebarchiesi@0
|
432
|
danielebarchiesi@0
|
433 /**
|
danielebarchiesi@0
|
434 * A user with 'administer filters' permission.
|
danielebarchiesi@0
|
435 *
|
danielebarchiesi@0
|
436 * @var object
|
danielebarchiesi@0
|
437 */
|
danielebarchiesi@0
|
438 protected $filter_admin_user;
|
danielebarchiesi@0
|
439
|
danielebarchiesi@0
|
440 /**
|
danielebarchiesi@0
|
441 * A user with permission to create and edit own content.
|
danielebarchiesi@0
|
442 *
|
danielebarchiesi@0
|
443 * @var object
|
danielebarchiesi@0
|
444 */
|
danielebarchiesi@0
|
445 protected $web_user;
|
danielebarchiesi@0
|
446
|
danielebarchiesi@0
|
447 /**
|
danielebarchiesi@0
|
448 * An object representing an allowed text format.
|
danielebarchiesi@0
|
449 *
|
danielebarchiesi@0
|
450 * @var object
|
danielebarchiesi@0
|
451 */
|
danielebarchiesi@0
|
452 protected $allowed_format;
|
danielebarchiesi@0
|
453
|
danielebarchiesi@0
|
454 /**
|
danielebarchiesi@0
|
455 * An object representing a disallowed text format.
|
danielebarchiesi@0
|
456 *
|
danielebarchiesi@0
|
457 * @var object
|
danielebarchiesi@0
|
458 */
|
danielebarchiesi@0
|
459 protected $disallowed_format;
|
danielebarchiesi@0
|
460
|
danielebarchiesi@0
|
461 public static function getInfo() {
|
danielebarchiesi@0
|
462 return array(
|
danielebarchiesi@0
|
463 'name' => 'Filter format access',
|
danielebarchiesi@0
|
464 'description' => 'Tests access to text formats.',
|
danielebarchiesi@0
|
465 'group' => 'Filter',
|
danielebarchiesi@0
|
466 );
|
danielebarchiesi@0
|
467 }
|
danielebarchiesi@0
|
468
|
danielebarchiesi@0
|
469 function setUp() {
|
danielebarchiesi@0
|
470 parent::setUp();
|
danielebarchiesi@0
|
471
|
danielebarchiesi@0
|
472 // Create a user who can administer text formats, but does not have
|
danielebarchiesi@0
|
473 // specific permission to use any of them.
|
danielebarchiesi@0
|
474 $this->filter_admin_user = $this->drupalCreateUser(array(
|
danielebarchiesi@0
|
475 'administer filters',
|
danielebarchiesi@0
|
476 'create page content',
|
danielebarchiesi@0
|
477 'edit any page content',
|
danielebarchiesi@0
|
478 ));
|
danielebarchiesi@0
|
479
|
danielebarchiesi@0
|
480 // Create two text formats.
|
danielebarchiesi@0
|
481 $this->drupalLogin($this->filter_admin_user);
|
danielebarchiesi@0
|
482 $formats = array();
|
danielebarchiesi@0
|
483 for ($i = 0; $i < 2; $i++) {
|
danielebarchiesi@0
|
484 $edit = array(
|
danielebarchiesi@0
|
485 'format' => drupal_strtolower($this->randomName()),
|
danielebarchiesi@0
|
486 'name' => $this->randomName(),
|
danielebarchiesi@0
|
487 );
|
danielebarchiesi@0
|
488 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
489 $this->resetFilterCaches();
|
danielebarchiesi@0
|
490 $formats[] = filter_format_load($edit['format']);
|
danielebarchiesi@0
|
491 }
|
danielebarchiesi@0
|
492 list($this->allowed_format, $this->disallowed_format) = $formats;
|
danielebarchiesi@0
|
493 $this->drupalLogout();
|
danielebarchiesi@0
|
494
|
danielebarchiesi@0
|
495 // Create a regular user with access to one of the formats.
|
danielebarchiesi@0
|
496 $this->web_user = $this->drupalCreateUser(array(
|
danielebarchiesi@0
|
497 'create page content',
|
danielebarchiesi@0
|
498 'edit any page content',
|
danielebarchiesi@0
|
499 filter_permission_name($this->allowed_format),
|
danielebarchiesi@0
|
500 ));
|
danielebarchiesi@0
|
501
|
danielebarchiesi@0
|
502 // Create an administrative user who has access to use both formats.
|
danielebarchiesi@0
|
503 $this->admin_user = $this->drupalCreateUser(array(
|
danielebarchiesi@0
|
504 'administer filters',
|
danielebarchiesi@0
|
505 'create page content',
|
danielebarchiesi@0
|
506 'edit any page content',
|
danielebarchiesi@0
|
507 filter_permission_name($this->allowed_format),
|
danielebarchiesi@0
|
508 filter_permission_name($this->disallowed_format),
|
danielebarchiesi@0
|
509 ));
|
danielebarchiesi@0
|
510 }
|
danielebarchiesi@0
|
511
|
danielebarchiesi@0
|
512 /**
|
danielebarchiesi@0
|
513 * Tests the Filter format access permissions functionality.
|
danielebarchiesi@0
|
514 */
|
danielebarchiesi@0
|
515 function testFormatPermissions() {
|
danielebarchiesi@0
|
516 // Make sure that a regular user only has access to the text format they
|
danielebarchiesi@0
|
517 // were granted access to, as well to the fallback format.
|
danielebarchiesi@0
|
518 $this->assertTrue(filter_access($this->allowed_format, $this->web_user), 'A regular user has access to a text format they were granted access to.');
|
danielebarchiesi@0
|
519 $this->assertFalse(filter_access($this->disallowed_format, $this->web_user), 'A regular user does not have access to a text format they were not granted access to.');
|
danielebarchiesi@0
|
520 $this->assertTrue(filter_access(filter_format_load(filter_fallback_format()), $this->web_user), 'A regular user has access to the fallback format.');
|
danielebarchiesi@0
|
521
|
danielebarchiesi@0
|
522 // Perform similar checks as above, but now against the entire list of
|
danielebarchiesi@0
|
523 // available formats for this user.
|
danielebarchiesi@0
|
524 $this->assertTrue(in_array($this->allowed_format->format, array_keys(filter_formats($this->web_user))), 'The allowed format appears in the list of available formats for a regular user.');
|
danielebarchiesi@0
|
525 $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_formats($this->web_user))), 'The disallowed format does not appear in the list of available formats for a regular user.');
|
danielebarchiesi@0
|
526 $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_formats($this->web_user))), 'The fallback format appears in the list of available formats for a regular user.');
|
danielebarchiesi@0
|
527
|
danielebarchiesi@0
|
528 // Make sure that a regular user only has permission to use the format
|
danielebarchiesi@0
|
529 // they were granted access to.
|
danielebarchiesi@0
|
530 $this->assertTrue(user_access(filter_permission_name($this->allowed_format), $this->web_user), 'A regular user has permission to use the allowed text format.');
|
danielebarchiesi@0
|
531 $this->assertFalse(user_access(filter_permission_name($this->disallowed_format), $this->web_user), 'A regular user does not have permission to use the disallowed text format.');
|
danielebarchiesi@0
|
532
|
danielebarchiesi@0
|
533 // Make sure that the allowed format appears on the node form and that
|
danielebarchiesi@0
|
534 // the disallowed format does not.
|
danielebarchiesi@0
|
535 $this->drupalLogin($this->web_user);
|
danielebarchiesi@0
|
536 $this->drupalGet('node/add/page');
|
danielebarchiesi@0
|
537 $langcode = LANGUAGE_NONE;
|
danielebarchiesi@0
|
538 $elements = $this->xpath('//select[@name=:name]/option', array(
|
danielebarchiesi@0
|
539 ':name' => "body[$langcode][0][format]",
|
danielebarchiesi@0
|
540 ':option' => $this->allowed_format->format,
|
danielebarchiesi@0
|
541 ));
|
danielebarchiesi@0
|
542 $options = array();
|
danielebarchiesi@0
|
543 foreach ($elements as $element) {
|
danielebarchiesi@0
|
544 $options[(string) $element['value']] = $element;
|
danielebarchiesi@0
|
545 }
|
danielebarchiesi@0
|
546 $this->assertTrue(isset($options[$this->allowed_format->format]), 'The allowed text format appears as an option when adding a new node.');
|
danielebarchiesi@0
|
547 $this->assertFalse(isset($options[$this->disallowed_format->format]), 'The disallowed text format does not appear as an option when adding a new node.');
|
danielebarchiesi@0
|
548 $this->assertTrue(isset($options[filter_fallback_format()]), 'The fallback format appears as an option when adding a new node.');
|
danielebarchiesi@0
|
549 }
|
danielebarchiesi@0
|
550
|
danielebarchiesi@0
|
551 /**
|
danielebarchiesi@0
|
552 * Tests if text format is available to a role.
|
danielebarchiesi@0
|
553 */
|
danielebarchiesi@0
|
554 function testFormatRoles() {
|
danielebarchiesi@0
|
555 // Get the role ID assigned to the regular user; it must be the maximum.
|
danielebarchiesi@0
|
556 $rid = max(array_keys($this->web_user->roles));
|
danielebarchiesi@0
|
557
|
danielebarchiesi@0
|
558 // Check that this role appears in the list of roles that have access to an
|
danielebarchiesi@0
|
559 // allowed text format, but does not appear in the list of roles that have
|
danielebarchiesi@0
|
560 // access to a disallowed text format.
|
danielebarchiesi@0
|
561 $this->assertTrue(in_array($rid, array_keys(filter_get_roles_by_format($this->allowed_format))), 'A role which has access to a text format appears in the list of roles that have access to that format.');
|
danielebarchiesi@0
|
562 $this->assertFalse(in_array($rid, array_keys(filter_get_roles_by_format($this->disallowed_format))), 'A role which does not have access to a text format does not appear in the list of roles that have access to that format.');
|
danielebarchiesi@0
|
563
|
danielebarchiesi@0
|
564 // Check that the correct text format appears in the list of formats
|
danielebarchiesi@0
|
565 // available to that role.
|
danielebarchiesi@0
|
566 $this->assertTrue(in_array($this->allowed_format->format, array_keys(filter_get_formats_by_role($rid))), 'A text format which a role has access to appears in the list of formats available to that role.');
|
danielebarchiesi@0
|
567 $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_get_formats_by_role($rid))), 'A text format which a role does not have access to does not appear in the list of formats available to that role.');
|
danielebarchiesi@0
|
568
|
danielebarchiesi@0
|
569 // Check that the fallback format is always allowed.
|
danielebarchiesi@0
|
570 $this->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_roles(), 'All roles have access to the fallback format.');
|
danielebarchiesi@0
|
571 $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_get_formats_by_role($rid))), 'The fallback format appears in the list of allowed formats for any role.');
|
danielebarchiesi@0
|
572 }
|
danielebarchiesi@0
|
573
|
danielebarchiesi@0
|
574 /**
|
danielebarchiesi@0
|
575 * Tests editing a page using a disallowed text format.
|
danielebarchiesi@0
|
576 *
|
danielebarchiesi@0
|
577 * Verifies that regular users and administrators are able to edit a page, but
|
danielebarchiesi@0
|
578 * not allowed to change the fields which use an inaccessible text format.
|
danielebarchiesi@0
|
579 * Also verifies that fields which use a text format that does not exist can
|
danielebarchiesi@0
|
580 * be edited by administrators only, but that the administrator is forced to
|
danielebarchiesi@0
|
581 * choose a new format before saving the page.
|
danielebarchiesi@0
|
582 */
|
danielebarchiesi@0
|
583 function testFormatWidgetPermissions() {
|
danielebarchiesi@0
|
584 $langcode = LANGUAGE_NONE;
|
danielebarchiesi@0
|
585 $title_key = "title";
|
danielebarchiesi@0
|
586 $body_value_key = "body[$langcode][0][value]";
|
danielebarchiesi@0
|
587 $body_format_key = "body[$langcode][0][format]";
|
danielebarchiesi@0
|
588
|
danielebarchiesi@0
|
589 // Create node to edit.
|
danielebarchiesi@0
|
590 $this->drupalLogin($this->admin_user);
|
danielebarchiesi@0
|
591 $edit = array();
|
danielebarchiesi@0
|
592 $edit['title'] = $this->randomName(8);
|
danielebarchiesi@0
|
593 $edit[$body_value_key] = $this->randomName(16);
|
danielebarchiesi@0
|
594 $edit[$body_format_key] = $this->disallowed_format->format;
|
danielebarchiesi@0
|
595 $this->drupalPost('node/add/page', $edit, t('Save'));
|
danielebarchiesi@0
|
596 $node = $this->drupalGetNodeByTitle($edit['title']);
|
danielebarchiesi@0
|
597
|
danielebarchiesi@0
|
598 // Try to edit with a less privileged user.
|
danielebarchiesi@0
|
599 $this->drupalLogin($this->web_user);
|
danielebarchiesi@0
|
600 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
601 $this->clickLink(t('Edit'));
|
danielebarchiesi@0
|
602
|
danielebarchiesi@0
|
603 // Verify that body field is read-only and contains replacement value.
|
danielebarchiesi@0
|
604 $this->assertFieldByXPath("//textarea[@name='$body_value_key' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.');
|
danielebarchiesi@0
|
605
|
danielebarchiesi@0
|
606 // Verify that title can be changed, but preview displays original body.
|
danielebarchiesi@0
|
607 $new_edit = array();
|
danielebarchiesi@0
|
608 $new_edit['title'] = $this->randomName(8);
|
danielebarchiesi@0
|
609 $this->drupalPost(NULL, $new_edit, t('Preview'));
|
danielebarchiesi@0
|
610 $this->assertText($edit[$body_value_key], 'Old body found in preview.');
|
danielebarchiesi@0
|
611
|
danielebarchiesi@0
|
612 // Save and verify that only the title was changed.
|
danielebarchiesi@0
|
613 $this->drupalPost(NULL, $new_edit, t('Save'));
|
danielebarchiesi@0
|
614 $this->assertNoText($edit['title'], 'Old title not found.');
|
danielebarchiesi@0
|
615 $this->assertText($new_edit['title'], 'New title found.');
|
danielebarchiesi@0
|
616 $this->assertText($edit[$body_value_key], 'Old body found.');
|
danielebarchiesi@0
|
617
|
danielebarchiesi@0
|
618 // Check that even an administrator with "administer filters" permission
|
danielebarchiesi@0
|
619 // cannot edit the body field if they do not have specific permission to
|
danielebarchiesi@0
|
620 // use its stored format. (This must be disallowed so that the
|
danielebarchiesi@0
|
621 // administrator is never forced to switch the text format to something
|
danielebarchiesi@0
|
622 // else.)
|
danielebarchiesi@0
|
623 $this->drupalLogin($this->filter_admin_user);
|
danielebarchiesi@0
|
624 $this->drupalGet('node/' . $node->nid . '/edit');
|
danielebarchiesi@0
|
625 $this->assertFieldByXPath("//textarea[@name='$body_value_key' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.');
|
danielebarchiesi@0
|
626
|
danielebarchiesi@0
|
627 // Disable the text format used above.
|
danielebarchiesi@0
|
628 filter_format_disable($this->disallowed_format);
|
danielebarchiesi@0
|
629 $this->resetFilterCaches();
|
danielebarchiesi@0
|
630
|
danielebarchiesi@0
|
631 // Log back in as the less privileged user and verify that the body field
|
danielebarchiesi@0
|
632 // is still disabled, since the less privileged user should not be able to
|
danielebarchiesi@0
|
633 // edit content that does not have an assigned format.
|
danielebarchiesi@0
|
634 $this->drupalLogin($this->web_user);
|
danielebarchiesi@0
|
635 $this->drupalGet('node/' . $node->nid . '/edit');
|
danielebarchiesi@0
|
636 $this->assertFieldByXPath("//textarea[@name='$body_value_key' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.');
|
danielebarchiesi@0
|
637
|
danielebarchiesi@0
|
638 // Log back in as the filter administrator and verify that the body field
|
danielebarchiesi@0
|
639 // can be edited.
|
danielebarchiesi@0
|
640 $this->drupalLogin($this->filter_admin_user);
|
danielebarchiesi@0
|
641 $this->drupalGet('node/' . $node->nid . '/edit');
|
danielebarchiesi@0
|
642 $this->assertNoFieldByXPath("//textarea[@name='$body_value_key' and @disabled='disabled']", NULL, 'Text format access denied message not found.');
|
danielebarchiesi@0
|
643 $this->assertFieldByXPath("//select[@name='$body_format_key']", NULL, 'Text format selector found.');
|
danielebarchiesi@0
|
644
|
danielebarchiesi@0
|
645 // Verify that trying to save the node without selecting a new text format
|
danielebarchiesi@0
|
646 // produces an error message, and does not result in the node being saved.
|
danielebarchiesi@0
|
647 $old_title = $new_edit['title'];
|
danielebarchiesi@0
|
648 $new_title = $this->randomName(8);
|
danielebarchiesi@0
|
649 $edit = array('title' => $new_title);
|
danielebarchiesi@0
|
650 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
651 $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.');
|
danielebarchiesi@0
|
652 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
653 $this->assertText($old_title, 'Old title found.');
|
danielebarchiesi@0
|
654 $this->assertNoText($new_title, 'New title not found.');
|
danielebarchiesi@0
|
655
|
danielebarchiesi@0
|
656 // Now select a new text format and make sure the node can be saved.
|
danielebarchiesi@0
|
657 $edit[$body_format_key] = filter_fallback_format();
|
danielebarchiesi@0
|
658 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
659 $this->assertUrl('node/' . $node->nid);
|
danielebarchiesi@0
|
660 $this->assertText($new_title, 'New title found.');
|
danielebarchiesi@0
|
661 $this->assertNoText($old_title, 'Old title not found.');
|
danielebarchiesi@0
|
662
|
danielebarchiesi@0
|
663 // Switch the text format to a new one, then disable that format and all
|
danielebarchiesi@0
|
664 // other formats on the site (leaving only the fallback format).
|
danielebarchiesi@0
|
665 $this->drupalLogin($this->admin_user);
|
danielebarchiesi@0
|
666 $edit = array($body_format_key => $this->allowed_format->format);
|
danielebarchiesi@0
|
667 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
668 $this->assertUrl('node/' . $node->nid);
|
danielebarchiesi@0
|
669 foreach (filter_formats() as $format) {
|
danielebarchiesi@0
|
670 if ($format->format != filter_fallback_format()) {
|
danielebarchiesi@0
|
671 filter_format_disable($format);
|
danielebarchiesi@0
|
672 }
|
danielebarchiesi@0
|
673 }
|
danielebarchiesi@0
|
674
|
danielebarchiesi@0
|
675 // Since there is now only one available text format, the widget for
|
danielebarchiesi@0
|
676 // selecting a text format would normally not display when the content is
|
danielebarchiesi@0
|
677 // edited. However, we need to verify that the filter administrator still
|
danielebarchiesi@0
|
678 // is forced to make a conscious choice to reassign the text to a different
|
danielebarchiesi@0
|
679 // format.
|
danielebarchiesi@0
|
680 $this->drupalLogin($this->filter_admin_user);
|
danielebarchiesi@0
|
681 $old_title = $new_title;
|
danielebarchiesi@0
|
682 $new_title = $this->randomName(8);
|
danielebarchiesi@0
|
683 $edit = array('title' => $new_title);
|
danielebarchiesi@0
|
684 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
685 $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.');
|
danielebarchiesi@0
|
686 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
687 $this->assertText($old_title, 'Old title found.');
|
danielebarchiesi@0
|
688 $this->assertNoText($new_title, 'New title not found.');
|
danielebarchiesi@0
|
689 $edit[$body_format_key] = filter_fallback_format();
|
danielebarchiesi@0
|
690 $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
|
danielebarchiesi@0
|
691 $this->assertUrl('node/' . $node->nid);
|
danielebarchiesi@0
|
692 $this->assertText($new_title, 'New title found.');
|
danielebarchiesi@0
|
693 $this->assertNoText($old_title, 'Old title not found.');
|
danielebarchiesi@0
|
694 }
|
danielebarchiesi@0
|
695
|
danielebarchiesi@0
|
696 /**
|
danielebarchiesi@0
|
697 * Rebuilds text format and permission caches in the thread running the tests.
|
danielebarchiesi@0
|
698 */
|
danielebarchiesi@0
|
699 protected function resetFilterCaches() {
|
danielebarchiesi@0
|
700 filter_formats_reset();
|
danielebarchiesi@0
|
701 $this->checkPermissions(array(), TRUE);
|
danielebarchiesi@0
|
702 }
|
danielebarchiesi@0
|
703 }
|
danielebarchiesi@0
|
704
|
danielebarchiesi@0
|
705 /**
|
danielebarchiesi@0
|
706 * Tests the default filter functionality in the Filter module.
|
danielebarchiesi@0
|
707 */
|
danielebarchiesi@0
|
708 class FilterDefaultFormatTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
709 public static function getInfo() {
|
danielebarchiesi@0
|
710 return array(
|
danielebarchiesi@0
|
711 'name' => 'Default text format functionality',
|
danielebarchiesi@0
|
712 'description' => 'Test the default text formats for different users.',
|
danielebarchiesi@0
|
713 'group' => 'Filter',
|
danielebarchiesi@0
|
714 );
|
danielebarchiesi@0
|
715 }
|
danielebarchiesi@0
|
716
|
danielebarchiesi@0
|
717 /**
|
danielebarchiesi@0
|
718 * Tests if the default text format is accessible to users.
|
danielebarchiesi@0
|
719 */
|
danielebarchiesi@0
|
720 function testDefaultTextFormats() {
|
danielebarchiesi@0
|
721 // Create two text formats, and two users. The first user has access to
|
danielebarchiesi@0
|
722 // both formats, but the second user only has access to the second one.
|
danielebarchiesi@0
|
723 $admin_user = $this->drupalCreateUser(array('administer filters'));
|
danielebarchiesi@0
|
724 $this->drupalLogin($admin_user);
|
danielebarchiesi@0
|
725 $formats = array();
|
danielebarchiesi@0
|
726 for ($i = 0; $i < 2; $i++) {
|
danielebarchiesi@0
|
727 $edit = array(
|
danielebarchiesi@0
|
728 'format' => drupal_strtolower($this->randomName()),
|
danielebarchiesi@0
|
729 'name' => $this->randomName(),
|
danielebarchiesi@0
|
730 );
|
danielebarchiesi@0
|
731 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
732 $this->resetFilterCaches();
|
danielebarchiesi@0
|
733 $formats[] = filter_format_load($edit['format']);
|
danielebarchiesi@0
|
734 }
|
danielebarchiesi@0
|
735 list($first_format, $second_format) = $formats;
|
danielebarchiesi@0
|
736 $first_user = $this->drupalCreateUser(array(filter_permission_name($first_format), filter_permission_name($second_format)));
|
danielebarchiesi@0
|
737 $second_user = $this->drupalCreateUser(array(filter_permission_name($second_format)));
|
danielebarchiesi@0
|
738
|
danielebarchiesi@0
|
739 // Adjust the weights so that the first and second formats (in that order)
|
danielebarchiesi@0
|
740 // are the two lowest weighted formats available to any user.
|
danielebarchiesi@0
|
741 $minimum_weight = db_query("SELECT MIN(weight) FROM {filter_format}")->fetchField();
|
danielebarchiesi@0
|
742 $edit = array();
|
danielebarchiesi@0
|
743 $edit['formats[' . $first_format->format . '][weight]'] = $minimum_weight - 2;
|
danielebarchiesi@0
|
744 $edit['formats[' . $second_format->format . '][weight]'] = $minimum_weight - 1;
|
danielebarchiesi@0
|
745 $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
|
danielebarchiesi@0
|
746 $this->resetFilterCaches();
|
danielebarchiesi@0
|
747
|
danielebarchiesi@0
|
748 // Check that each user's default format is the lowest weighted format that
|
danielebarchiesi@0
|
749 // the user has access to.
|
danielebarchiesi@0
|
750 $this->assertEqual(filter_default_format($first_user), $first_format->format, "The first user's default format is the lowest weighted format that the user has access to.");
|
danielebarchiesi@0
|
751 $this->assertEqual(filter_default_format($second_user), $second_format->format, "The second user's default format is the lowest weighted format that the user has access to, and is different than the first user's.");
|
danielebarchiesi@0
|
752
|
danielebarchiesi@0
|
753 // Reorder the two formats, and check that both users now have the same
|
danielebarchiesi@0
|
754 // default.
|
danielebarchiesi@0
|
755 $edit = array();
|
danielebarchiesi@0
|
756 $edit['formats[' . $second_format->format . '][weight]'] = $minimum_weight - 3;
|
danielebarchiesi@0
|
757 $this->drupalPost('admin/config/content/formats', $edit, t('Save changes'));
|
danielebarchiesi@0
|
758 $this->resetFilterCaches();
|
danielebarchiesi@0
|
759 $this->assertEqual(filter_default_format($first_user), filter_default_format($second_user), 'After the formats are reordered, both users have the same default format.');
|
danielebarchiesi@0
|
760 }
|
danielebarchiesi@0
|
761
|
danielebarchiesi@0
|
762 /**
|
danielebarchiesi@0
|
763 * Rebuilds text format and permission caches in the thread running the tests.
|
danielebarchiesi@0
|
764 */
|
danielebarchiesi@0
|
765 protected function resetFilterCaches() {
|
danielebarchiesi@0
|
766 filter_formats_reset();
|
danielebarchiesi@0
|
767 $this->checkPermissions(array(), TRUE);
|
danielebarchiesi@0
|
768 }
|
danielebarchiesi@0
|
769 }
|
danielebarchiesi@0
|
770
|
danielebarchiesi@0
|
771 /**
|
danielebarchiesi@0
|
772 * Tests the behavior of check_markup() when it is called without text format.
|
danielebarchiesi@0
|
773 */
|
danielebarchiesi@0
|
774 class FilterNoFormatTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
775 public static function getInfo() {
|
danielebarchiesi@0
|
776 return array(
|
danielebarchiesi@0
|
777 'name' => 'Unassigned text format functionality',
|
danielebarchiesi@0
|
778 'description' => 'Test the behavior of check_markup() when it is called without a text format.',
|
danielebarchiesi@0
|
779 'group' => 'Filter',
|
danielebarchiesi@0
|
780 );
|
danielebarchiesi@0
|
781 }
|
danielebarchiesi@0
|
782
|
danielebarchiesi@0
|
783 /**
|
danielebarchiesi@0
|
784 * Tests text without format.
|
danielebarchiesi@0
|
785 *
|
danielebarchiesi@0
|
786 * Tests if text with no format is filtered the same way as text in the
|
danielebarchiesi@0
|
787 * fallback format.
|
danielebarchiesi@0
|
788 */
|
danielebarchiesi@0
|
789 function testCheckMarkupNoFormat() {
|
danielebarchiesi@0
|
790 // Create some text. Include some HTML and line breaks, so we get a good
|
danielebarchiesi@0
|
791 // test of the filtering that is applied to it.
|
danielebarchiesi@0
|
792 $text = "<strong>" . $this->randomName(32) . "</strong>\n\n<div>" . $this->randomName(32) . "</div>";
|
danielebarchiesi@0
|
793
|
danielebarchiesi@0
|
794 // Make sure that when this text is run through check_markup() with no text
|
danielebarchiesi@0
|
795 // format, it is filtered as though it is in the fallback format.
|
danielebarchiesi@0
|
796 $this->assertEqual(check_markup($text), check_markup($text, filter_fallback_format()), 'Text with no format is filtered the same as text in the fallback format.');
|
danielebarchiesi@0
|
797 }
|
danielebarchiesi@0
|
798 }
|
danielebarchiesi@0
|
799
|
danielebarchiesi@0
|
800 /**
|
danielebarchiesi@0
|
801 * Security tests for missing/vanished text formats or filters.
|
danielebarchiesi@0
|
802 */
|
danielebarchiesi@0
|
803 class FilterSecurityTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
804 public static function getInfo() {
|
danielebarchiesi@0
|
805 return array(
|
danielebarchiesi@0
|
806 'name' => 'Security',
|
danielebarchiesi@0
|
807 'description' => 'Test the behavior of check_markup() when a filter or text format vanishes.',
|
danielebarchiesi@0
|
808 'group' => 'Filter',
|
danielebarchiesi@0
|
809 );
|
danielebarchiesi@0
|
810 }
|
danielebarchiesi@0
|
811
|
danielebarchiesi@0
|
812 function setUp() {
|
danielebarchiesi@0
|
813 parent::setUp('php', 'filter_test');
|
danielebarchiesi@0
|
814 $this->admin_user = $this->drupalCreateUser(array('administer modules', 'administer filters', 'administer site configuration'));
|
danielebarchiesi@0
|
815 $this->drupalLogin($this->admin_user);
|
danielebarchiesi@0
|
816 }
|
danielebarchiesi@0
|
817
|
danielebarchiesi@0
|
818 /**
|
danielebarchiesi@0
|
819 * Tests removal of filtered content when an active filter is disabled.
|
danielebarchiesi@0
|
820 *
|
danielebarchiesi@0
|
821 * Tests that filtered content is emptied when an actively used filter module
|
danielebarchiesi@0
|
822 * is disabled.
|
danielebarchiesi@0
|
823 */
|
danielebarchiesi@0
|
824 function testDisableFilterModule() {
|
danielebarchiesi@0
|
825 // Create a new node.
|
danielebarchiesi@0
|
826 $node = $this->drupalCreateNode(array('promote' => 1));
|
danielebarchiesi@0
|
827 $body_raw = $node->body[LANGUAGE_NONE][0]['value'];
|
danielebarchiesi@0
|
828 $format_id = $node->body[LANGUAGE_NONE][0]['format'];
|
danielebarchiesi@0
|
829 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
830 $this->assertText($body_raw, 'Node body found.');
|
danielebarchiesi@0
|
831
|
danielebarchiesi@0
|
832 // Enable the filter_test_replace filter.
|
danielebarchiesi@0
|
833 $edit = array(
|
danielebarchiesi@0
|
834 'filters[filter_test_replace][status]' => 1,
|
danielebarchiesi@0
|
835 );
|
danielebarchiesi@0
|
836 $this->drupalPost('admin/config/content/formats/' . $format_id, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
837
|
danielebarchiesi@0
|
838 // Verify that filter_test_replace filter replaced the content.
|
danielebarchiesi@0
|
839 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
840 $this->assertNoText($body_raw, 'Node body not found.');
|
danielebarchiesi@0
|
841 $this->assertText('Filter: Testing filter', 'Testing filter output found.');
|
danielebarchiesi@0
|
842
|
danielebarchiesi@0
|
843 // Disable the text format entirely.
|
danielebarchiesi@0
|
844 $this->drupalPost('admin/config/content/formats/' . $format_id . '/disable', array(), t('Disable'));
|
danielebarchiesi@0
|
845
|
danielebarchiesi@0
|
846 // Verify that the content is empty, because the text format does not exist.
|
danielebarchiesi@0
|
847 $this->drupalGet('node/' . $node->nid);
|
danielebarchiesi@0
|
848 $this->assertNoText($body_raw, 'Node body not found.');
|
danielebarchiesi@0
|
849 }
|
danielebarchiesi@0
|
850 }
|
danielebarchiesi@0
|
851
|
danielebarchiesi@0
|
852 /**
|
danielebarchiesi@0
|
853 * Unit tests for core filters.
|
danielebarchiesi@0
|
854 */
|
danielebarchiesi@0
|
855 class FilterUnitTestCase extends DrupalUnitTestCase {
|
danielebarchiesi@0
|
856 public static function getInfo() {
|
danielebarchiesi@0
|
857 return array(
|
danielebarchiesi@0
|
858 'name' => 'Filter module filters',
|
danielebarchiesi@0
|
859 'description' => 'Tests Filter module filters individually.',
|
danielebarchiesi@0
|
860 'group' => 'Filter',
|
danielebarchiesi@0
|
861 );
|
danielebarchiesi@0
|
862 }
|
danielebarchiesi@0
|
863
|
danielebarchiesi@0
|
864 /**
|
danielebarchiesi@0
|
865 * Tests the line break filter.
|
danielebarchiesi@0
|
866 */
|
danielebarchiesi@0
|
867 function testLineBreakFilter() {
|
danielebarchiesi@0
|
868 // Setup dummy filter object.
|
danielebarchiesi@0
|
869 $filter = new stdClass();
|
danielebarchiesi@0
|
870 $filter->callback = '_filter_autop';
|
danielebarchiesi@0
|
871
|
danielebarchiesi@0
|
872 // Since the line break filter naturally needs plenty of newlines in test
|
danielebarchiesi@0
|
873 // strings and expectations, we're using "\n" instead of regular newlines
|
danielebarchiesi@0
|
874 // here.
|
danielebarchiesi@0
|
875 $tests = array(
|
danielebarchiesi@0
|
876 // Single line breaks should be changed to <br /> tags, while paragraphs
|
danielebarchiesi@0
|
877 // separated with double line breaks should be enclosed with <p></p> tags.
|
danielebarchiesi@0
|
878 "aaa\nbbb\n\nccc" => array(
|
danielebarchiesi@0
|
879 "<p>aaa<br />\nbbb</p>\n<p>ccc</p>" => TRUE,
|
danielebarchiesi@0
|
880 ),
|
danielebarchiesi@0
|
881 // Skip contents of certain block tags entirely.
|
danielebarchiesi@0
|
882 "<script>aaa\nbbb\n\nccc</script>
|
danielebarchiesi@0
|
883 <style>aaa\nbbb\n\nccc</style>
|
danielebarchiesi@0
|
884 <pre>aaa\nbbb\n\nccc</pre>
|
danielebarchiesi@0
|
885 <object>aaa\nbbb\n\nccc</object>
|
danielebarchiesi@0
|
886 <iframe>aaa\nbbb\n\nccc</iframe>
|
danielebarchiesi@0
|
887 " => array(
|
danielebarchiesi@0
|
888 "<script>aaa\nbbb\n\nccc</script>" => TRUE,
|
danielebarchiesi@0
|
889 "<style>aaa\nbbb\n\nccc</style>" => TRUE,
|
danielebarchiesi@0
|
890 "<pre>aaa\nbbb\n\nccc</pre>" => TRUE,
|
danielebarchiesi@0
|
891 "<object>aaa\nbbb\n\nccc</object>" => TRUE,
|
danielebarchiesi@0
|
892 "<iframe>aaa\nbbb\n\nccc</iframe>" => TRUE,
|
danielebarchiesi@0
|
893 ),
|
danielebarchiesi@0
|
894 // Skip comments entirely.
|
danielebarchiesi@0
|
895 "One. <!-- comment --> Two.\n<!--\nThree.\n-->\n" => array(
|
danielebarchiesi@0
|
896 '<!-- comment -->' => TRUE,
|
danielebarchiesi@0
|
897 "<!--\nThree.\n-->" => TRUE,
|
danielebarchiesi@0
|
898 ),
|
danielebarchiesi@0
|
899 // Resulting HTML should produce matching paragraph tags.
|
danielebarchiesi@0
|
900 '<p><div> </div></p>' => array(
|
danielebarchiesi@0
|
901 "<p>\n<div> </div>\n</p>" => TRUE,
|
danielebarchiesi@0
|
902 ),
|
danielebarchiesi@0
|
903 '<div><p> </p></div>' => array(
|
danielebarchiesi@0
|
904 "<div>\n</div>" => TRUE,
|
danielebarchiesi@0
|
905 ),
|
danielebarchiesi@0
|
906 '<blockquote><pre>aaa</pre></blockquote>' => array(
|
danielebarchiesi@0
|
907 "<blockquote><pre>aaa</pre></blockquote>" => TRUE,
|
danielebarchiesi@0
|
908 ),
|
danielebarchiesi@0
|
909 "<pre>aaa\nbbb\nccc</pre>\nddd\neee" => array(
|
danielebarchiesi@0
|
910 "<pre>aaa\nbbb\nccc</pre>" => TRUE,
|
danielebarchiesi@0
|
911 "<p>ddd<br />\neee</p>" => TRUE,
|
danielebarchiesi@0
|
912 ),
|
danielebarchiesi@0
|
913 // Comments remain unchanged and subsequent lines/paragraphs are
|
danielebarchiesi@0
|
914 // transformed normally.
|
danielebarchiesi@0
|
915 "aaa<!--comment-->\n\nbbb\n\nccc\n\nddd<!--comment\nwith linebreak-->\n\neee\n\nfff" => array(
|
danielebarchiesi@0
|
916 "<p>aaa</p>\n<!--comment--><p>\nbbb</p>\n<p>ccc</p>\n<p>ddd</p>" => TRUE,
|
danielebarchiesi@0
|
917 "<!--comment\nwith linebreak--><p>\neee</p>\n<p>fff</p>" => TRUE,
|
danielebarchiesi@0
|
918 ),
|
danielebarchiesi@0
|
919 // Check that a comment in a PRE will result that the text after
|
danielebarchiesi@0
|
920 // the comment, but still in PRE, is not transformed.
|
danielebarchiesi@0
|
921 "<pre>aaa\nbbb<!-- comment -->\n\nccc</pre>\nddd" => array(
|
danielebarchiesi@0
|
922 "<pre>aaa\nbbb<!-- comment -->\n\nccc</pre>" => TRUE,
|
danielebarchiesi@0
|
923 ),
|
danielebarchiesi@0
|
924 // Bug 810824, paragraphs were appearing around iframe tags.
|
danielebarchiesi@0
|
925 "<iframe>aaa</iframe>\n\n" => array(
|
danielebarchiesi@0
|
926 "<p><iframe>aaa</iframe></p>" => FALSE,
|
danielebarchiesi@0
|
927 ),
|
danielebarchiesi@0
|
928 );
|
danielebarchiesi@0
|
929 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
930
|
danielebarchiesi@0
|
931 // Very long string hitting PCRE limits.
|
danielebarchiesi@0
|
932 $limit = max(ini_get('pcre.backtrack_limit'), ini_get('pcre.recursion_limit'));
|
danielebarchiesi@0
|
933 $source = $this->randomName($limit);
|
danielebarchiesi@0
|
934 $result = _filter_autop($source);
|
danielebarchiesi@0
|
935 $success = $this->assertEqual($result, '<p>' . $source . "</p>\n", 'Line break filter can process very long strings.');
|
danielebarchiesi@0
|
936 if (!$success) {
|
danielebarchiesi@0
|
937 $this->verbose("\n" . $source . "\n<hr />\n" . $result);
|
danielebarchiesi@0
|
938 }
|
danielebarchiesi@0
|
939 }
|
danielebarchiesi@0
|
940
|
danielebarchiesi@0
|
941 /**
|
danielebarchiesi@0
|
942 * Tests limiting allowed tags and XSS prevention.
|
danielebarchiesi@0
|
943 *
|
danielebarchiesi@0
|
944 * XSS tests assume that script is disallowed by default and src is allowed
|
danielebarchiesi@0
|
945 * by default, but on* and style attributes are disallowed.
|
danielebarchiesi@0
|
946 *
|
danielebarchiesi@0
|
947 * Script injection vectors mostly adopted from http://ha.ckers.org/xss.html.
|
danielebarchiesi@0
|
948 *
|
danielebarchiesi@0
|
949 * Relevant CVEs:
|
danielebarchiesi@0
|
950 * - CVE-2002-1806, ~CVE-2005-0682, ~CVE-2005-2106, CVE-2005-3973,
|
danielebarchiesi@0
|
951 * CVE-2006-1226 (= rev. 1.112?), CVE-2008-0273, CVE-2008-3740.
|
danielebarchiesi@0
|
952 */
|
danielebarchiesi@0
|
953 function testFilterXSS() {
|
danielebarchiesi@0
|
954 // Tag stripping, different ways to work around removal of HTML tags.
|
danielebarchiesi@0
|
955 $f = filter_xss('<script>alert(0)</script>');
|
danielebarchiesi@0
|
956 $this->assertNoNormalized($f, 'script', 'HTML tag stripping -- simple script without special characters.');
|
danielebarchiesi@0
|
957
|
danielebarchiesi@0
|
958 $f = filter_xss('<script src="http://www.example.com" />');
|
danielebarchiesi@0
|
959 $this->assertNoNormalized($f, 'script', 'HTML tag stripping -- empty script with source.');
|
danielebarchiesi@0
|
960
|
danielebarchiesi@0
|
961 $f = filter_xss('<ScRipt sRc=http://www.example.com/>');
|
danielebarchiesi@0
|
962 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- varying case.');
|
danielebarchiesi@0
|
963
|
danielebarchiesi@0
|
964 $f = filter_xss("<script\nsrc\n=\nhttp://www.example.com/\n>");
|
danielebarchiesi@0
|
965 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- multiline tag.');
|
danielebarchiesi@0
|
966
|
danielebarchiesi@0
|
967 $f = filter_xss('<script/a src=http://www.example.com/a.js></script>');
|
danielebarchiesi@0
|
968 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- non whitespace character after tag name.');
|
danielebarchiesi@0
|
969
|
danielebarchiesi@0
|
970 $f = filter_xss('<script/src=http://www.example.com/a.js></script>');
|
danielebarchiesi@0
|
971 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- no space between tag and attribute.');
|
danielebarchiesi@0
|
972
|
danielebarchiesi@0
|
973 // Null between < and tag name works at least with IE6.
|
danielebarchiesi@0
|
974 $f = filter_xss("<\0scr\0ipt>alert(0)</script>");
|
danielebarchiesi@0
|
975 $this->assertNoNormalized($f, 'ipt', 'HTML tag stripping evasion -- breaking HTML with nulls.');
|
danielebarchiesi@0
|
976
|
danielebarchiesi@0
|
977 $f = filter_xss("<scrscriptipt src=http://www.example.com/a.js>");
|
danielebarchiesi@0
|
978 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- filter just removing "script".');
|
danielebarchiesi@0
|
979
|
danielebarchiesi@0
|
980 $f = filter_xss('<<script>alert(0);//<</script>');
|
danielebarchiesi@0
|
981 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- double opening brackets.');
|
danielebarchiesi@0
|
982
|
danielebarchiesi@0
|
983 $f = filter_xss('<script src=http://www.example.com/a.js?<b>');
|
danielebarchiesi@0
|
984 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- no closing tag.');
|
danielebarchiesi@0
|
985
|
danielebarchiesi@0
|
986 // DRUPAL-SA-2008-047: This doesn't seem exploitable, but the filter should
|
danielebarchiesi@0
|
987 // work consistently.
|
danielebarchiesi@0
|
988 $f = filter_xss('<script>>');
|
danielebarchiesi@0
|
989 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- double closing tag.');
|
danielebarchiesi@0
|
990
|
danielebarchiesi@0
|
991 $f = filter_xss('<script src=//www.example.com/.a>');
|
danielebarchiesi@0
|
992 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- no scheme or ending slash.');
|
danielebarchiesi@0
|
993
|
danielebarchiesi@0
|
994 $f = filter_xss('<script src=http://www.example.com/.a');
|
danielebarchiesi@0
|
995 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- no closing bracket.');
|
danielebarchiesi@0
|
996
|
danielebarchiesi@0
|
997 $f = filter_xss('<script src=http://www.example.com/ <');
|
danielebarchiesi@0
|
998 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- opening instead of closing bracket.');
|
danielebarchiesi@0
|
999
|
danielebarchiesi@0
|
1000 $f = filter_xss('<nosuchtag attribute="newScriptInjectionVector">');
|
danielebarchiesi@0
|
1001 $this->assertNoNormalized($f, 'nosuchtag', 'HTML tag stripping evasion -- unknown tag.');
|
danielebarchiesi@0
|
1002
|
danielebarchiesi@0
|
1003 $f = filter_xss('<?xml:namespace ns="urn:schemas-microsoft-com:time">');
|
danielebarchiesi@0
|
1004 $this->assertTrue(stripos($f, '<?xml') === FALSE, 'HTML tag stripping evasion -- starting with a question sign (processing instructions).');
|
danielebarchiesi@0
|
1005
|
danielebarchiesi@0
|
1006 $f = filter_xss('<t:set attributeName="innerHTML" to="<script defer>alert(0)</script>">');
|
danielebarchiesi@0
|
1007 $this->assertNoNormalized($f, 't:set', 'HTML tag stripping evasion -- colon in the tag name (namespaces\' tricks).');
|
danielebarchiesi@0
|
1008
|
danielebarchiesi@0
|
1009 $f = filter_xss('<img """><script>alert(0)</script>', array('img'));
|
danielebarchiesi@0
|
1010 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- a malformed image tag.');
|
danielebarchiesi@0
|
1011
|
danielebarchiesi@0
|
1012 $f = filter_xss('<blockquote><script>alert(0)</script></blockquote>', array('blockquote'));
|
danielebarchiesi@0
|
1013 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- script in a blockqoute.');
|
danielebarchiesi@0
|
1014
|
danielebarchiesi@0
|
1015 $f = filter_xss("<!--[if true]><script>alert(0)</script><![endif]-->");
|
danielebarchiesi@0
|
1016 $this->assertNoNormalized($f, 'script', 'HTML tag stripping evasion -- script within a comment.');
|
danielebarchiesi@0
|
1017
|
danielebarchiesi@0
|
1018 // Dangerous attributes removal.
|
danielebarchiesi@0
|
1019 $f = filter_xss('<p onmouseover="http://www.example.com/">', array('p'));
|
danielebarchiesi@0
|
1020 $this->assertNoNormalized($f, 'onmouseover', 'HTML filter attributes removal -- events, no evasion.');
|
danielebarchiesi@0
|
1021
|
danielebarchiesi@0
|
1022 $f = filter_xss('<li style="list-style-image: url(javascript:alert(0))">', array('li'));
|
danielebarchiesi@0
|
1023 $this->assertNoNormalized($f, 'style', 'HTML filter attributes removal -- style, no evasion.');
|
danielebarchiesi@0
|
1024
|
danielebarchiesi@0
|
1025 $f = filter_xss('<img onerror =alert(0)>', array('img'));
|
danielebarchiesi@0
|
1026 $this->assertNoNormalized($f, 'onerror', 'HTML filter attributes removal evasion -- spaces before equals sign.');
|
danielebarchiesi@0
|
1027
|
danielebarchiesi@0
|
1028 $f = filter_xss('<img onabort!#$%&()*~+-_.,:;?@[/|\]^`=alert(0)>', array('img'));
|
danielebarchiesi@0
|
1029 $this->assertNoNormalized($f, 'onabort', 'HTML filter attributes removal evasion -- non alphanumeric characters before equals sign.');
|
danielebarchiesi@0
|
1030
|
danielebarchiesi@0
|
1031 $f = filter_xss('<img oNmediAError=alert(0)>', array('img'));
|
danielebarchiesi@0
|
1032 $this->assertNoNormalized($f, 'onmediaerror', 'HTML filter attributes removal evasion -- varying case.');
|
danielebarchiesi@0
|
1033
|
danielebarchiesi@0
|
1034 // Works at least with IE6.
|
danielebarchiesi@0
|
1035 $f = filter_xss("<img o\0nfocus\0=alert(0)>", array('img'));
|
danielebarchiesi@0
|
1036 $this->assertNoNormalized($f, 'focus', 'HTML filter attributes removal evasion -- breaking with nulls.');
|
danielebarchiesi@0
|
1037
|
danielebarchiesi@0
|
1038 // Only whitelisted scheme names allowed in attributes.
|
danielebarchiesi@0
|
1039 $f = filter_xss('<img src="javascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1040 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing -- no evasion.');
|
danielebarchiesi@0
|
1041
|
danielebarchiesi@0
|
1042 $f = filter_xss('<img src=javascript:alert(0)>', array('img'));
|
danielebarchiesi@0
|
1043 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- no quotes.');
|
danielebarchiesi@0
|
1044
|
danielebarchiesi@0
|
1045 // A bit like CVE-2006-0070.
|
danielebarchiesi@0
|
1046 $f = filter_xss('<img src="javascript:confirm(0)">', array('img'));
|
danielebarchiesi@0
|
1047 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- no alert ;)');
|
danielebarchiesi@0
|
1048
|
danielebarchiesi@0
|
1049 $f = filter_xss('<img src=`javascript:alert(0)`>', array('img'));
|
danielebarchiesi@0
|
1050 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- grave accents.');
|
danielebarchiesi@0
|
1051
|
danielebarchiesi@0
|
1052 $f = filter_xss('<img dynsrc="javascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1053 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing -- rare attribute.');
|
danielebarchiesi@0
|
1054
|
danielebarchiesi@0
|
1055 $f = filter_xss('<table background="javascript:alert(0)">', array('table'));
|
danielebarchiesi@0
|
1056 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing -- another tag.');
|
danielebarchiesi@0
|
1057
|
danielebarchiesi@0
|
1058 $f = filter_xss('<base href="javascript:alert(0);//">', array('base'));
|
danielebarchiesi@0
|
1059 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing -- one more attribute and tag.');
|
danielebarchiesi@0
|
1060
|
danielebarchiesi@0
|
1061 $f = filter_xss('<img src="jaVaSCriPt:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1062 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- varying case.');
|
danielebarchiesi@0
|
1063
|
danielebarchiesi@0
|
1064 $f = filter_xss('<img src=javascript:alert(0)>', array('img'));
|
danielebarchiesi@0
|
1065 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- UTF-8 decimal encoding.');
|
danielebarchiesi@0
|
1066
|
danielebarchiesi@0
|
1067 $f = filter_xss('<img src=javascript:alert(0)>', array('img'));
|
danielebarchiesi@0
|
1068 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- long UTF-8 encoding.');
|
danielebarchiesi@0
|
1069
|
danielebarchiesi@0
|
1070 $f = filter_xss('<img src=javascript:alert(0)>', array('img'));
|
danielebarchiesi@0
|
1071 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- UTF-8 hex encoding.');
|
danielebarchiesi@0
|
1072
|
danielebarchiesi@0
|
1073 $f = filter_xss("<img src=\"jav\tascript:alert(0)\">", array('img'));
|
danielebarchiesi@0
|
1074 $this->assertNoNormalized($f, 'script', 'HTML scheme clearing evasion -- an embedded tab.');
|
danielebarchiesi@0
|
1075
|
danielebarchiesi@0
|
1076 $f = filter_xss('<img src="jav	ascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1077 $this->assertNoNormalized($f, 'script', 'HTML scheme clearing evasion -- an encoded, embedded tab.');
|
danielebarchiesi@0
|
1078
|
danielebarchiesi@0
|
1079 $f = filter_xss('<img src="jav
ascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1080 $this->assertNoNormalized($f, 'script', 'HTML scheme clearing evasion -- an encoded, embedded newline.');
|
danielebarchiesi@0
|
1081
|
danielebarchiesi@0
|
1082 // With 
 this test would fail, but the entity gets turned into
|
danielebarchiesi@0
|
1083 // &#xD;, so it's OK.
|
danielebarchiesi@0
|
1084 $f = filter_xss('<img src="jav
ascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1085 $this->assertNoNormalized($f, 'script', 'HTML scheme clearing evasion -- an encoded, embedded carriage return.');
|
danielebarchiesi@0
|
1086
|
danielebarchiesi@0
|
1087 $f = filter_xss("<img src=\"\n\n\nj\na\nva\ns\ncript:alert(0)\">", array('img'));
|
danielebarchiesi@0
|
1088 $this->assertNoNormalized($f, 'cript', 'HTML scheme clearing evasion -- broken into many lines.');
|
danielebarchiesi@0
|
1089
|
danielebarchiesi@0
|
1090 $f = filter_xss("<img src=\"jav\0a\0\0cript:alert(0)\">", array('img'));
|
danielebarchiesi@0
|
1091 $this->assertNoNormalized($f, 'cript', 'HTML scheme clearing evasion -- embedded nulls.');
|
danielebarchiesi@0
|
1092
|
danielebarchiesi@0
|
1093 $f = filter_xss('<img src="  javascript:alert(0)">', array('img'));
|
danielebarchiesi@0
|
1094 $this->assertNoNormalized($f, 'javascript', 'HTML scheme clearing evasion -- spaces and metacharacters before scheme.');
|
danielebarchiesi@0
|
1095
|
danielebarchiesi@0
|
1096 $f = filter_xss('<img src="vbscript:msgbox(0)">', array('img'));
|
danielebarchiesi@0
|
1097 $this->assertNoNormalized($f, 'vbscript', 'HTML scheme clearing evasion -- another scheme.');
|
danielebarchiesi@0
|
1098
|
danielebarchiesi@0
|
1099 $f = filter_xss('<img src="nosuchscheme:notice(0)">', array('img'));
|
danielebarchiesi@0
|
1100 $this->assertNoNormalized($f, 'nosuchscheme', 'HTML scheme clearing evasion -- unknown scheme.');
|
danielebarchiesi@0
|
1101
|
danielebarchiesi@0
|
1102 // Netscape 4.x javascript entities.
|
danielebarchiesi@0
|
1103 $f = filter_xss('<br size="&{alert(0)}">', array('br'));
|
danielebarchiesi@0
|
1104 $this->assertNoNormalized($f, 'alert', 'Netscape 4.x javascript entities.');
|
danielebarchiesi@0
|
1105
|
danielebarchiesi@0
|
1106 // DRUPAL-SA-2008-006: Invalid UTF-8, these only work as reflected XSS with
|
danielebarchiesi@0
|
1107 // Internet Explorer 6.
|
danielebarchiesi@0
|
1108 $f = filter_xss("<p arg=\"\xe0\">\" style=\"background-image: url(javascript:alert(0));\"\xe0<p>", array('p'));
|
danielebarchiesi@0
|
1109 $this->assertNoNormalized($f, 'style', 'HTML filter -- invalid UTF-8.');
|
danielebarchiesi@0
|
1110
|
danielebarchiesi@0
|
1111 $f = filter_xss("\xc0aaa");
|
danielebarchiesi@0
|
1112 $this->assertEqual($f, '', 'HTML filter -- overlong UTF-8 sequences.');
|
danielebarchiesi@0
|
1113
|
danielebarchiesi@0
|
1114 $f = filter_xss("Who's Online");
|
danielebarchiesi@0
|
1115 $this->assertNormalized($f, "who's online", 'HTML filter -- html entity number');
|
danielebarchiesi@0
|
1116
|
danielebarchiesi@0
|
1117 $f = filter_xss("Who&#039;s Online");
|
danielebarchiesi@0
|
1118 $this->assertNormalized($f, "who's online", 'HTML filter -- encoded html entity number');
|
danielebarchiesi@0
|
1119
|
danielebarchiesi@0
|
1120 $f = filter_xss("Who&amp;#039; Online");
|
danielebarchiesi@0
|
1121 $this->assertNormalized($f, "who&#039; online", 'HTML filter -- double encoded html entity number');
|
danielebarchiesi@0
|
1122 }
|
danielebarchiesi@0
|
1123
|
danielebarchiesi@0
|
1124 /**
|
danielebarchiesi@0
|
1125 * Tests filter settings, defaults, access restrictions and similar.
|
danielebarchiesi@0
|
1126 *
|
danielebarchiesi@0
|
1127 * @todo This is for functions like filter_filter and check_markup, whose
|
danielebarchiesi@0
|
1128 * functionality is not completely focused on filtering. Some ideas:
|
danielebarchiesi@0
|
1129 * restricting formats according to user permissions, proper cache
|
danielebarchiesi@0
|
1130 * handling, defaults -- allowed tags/attributes/protocols.
|
danielebarchiesi@0
|
1131 *
|
danielebarchiesi@0
|
1132 * @todo It is possible to add script, iframe etc. to allowed tags, but this
|
danielebarchiesi@0
|
1133 * makes HTML filter completely ineffective.
|
danielebarchiesi@0
|
1134 *
|
danielebarchiesi@0
|
1135 * @todo Class, id, name and xmlns should be added to disallowed attributes,
|
danielebarchiesi@0
|
1136 * or better a whitelist approach should be used for that too.
|
danielebarchiesi@0
|
1137 */
|
danielebarchiesi@0
|
1138 function testHtmlFilter() {
|
danielebarchiesi@0
|
1139 // Setup dummy filter object.
|
danielebarchiesi@0
|
1140 $filter = new stdClass();
|
danielebarchiesi@0
|
1141 $filter->settings = array(
|
danielebarchiesi@0
|
1142 'allowed_html' => '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>',
|
danielebarchiesi@0
|
1143 'filter_html_help' => 1,
|
danielebarchiesi@0
|
1144 'filter_html_nofollow' => 0,
|
danielebarchiesi@0
|
1145 );
|
danielebarchiesi@0
|
1146
|
danielebarchiesi@0
|
1147 // HTML filter is not able to secure some tags, these should never be
|
danielebarchiesi@0
|
1148 // allowed.
|
danielebarchiesi@0
|
1149 $f = _filter_html('<script />', $filter);
|
danielebarchiesi@0
|
1150 $this->assertNoNormalized($f, 'script', 'HTML filter should always remove script tags.');
|
danielebarchiesi@0
|
1151
|
danielebarchiesi@0
|
1152 $f = _filter_html('<iframe />', $filter);
|
danielebarchiesi@0
|
1153 $this->assertNoNormalized($f, 'iframe', 'HTML filter should always remove iframe tags.');
|
danielebarchiesi@0
|
1154
|
danielebarchiesi@0
|
1155 $f = _filter_html('<object />', $filter);
|
danielebarchiesi@0
|
1156 $this->assertNoNormalized($f, 'object', 'HTML filter should always remove object tags.');
|
danielebarchiesi@0
|
1157
|
danielebarchiesi@0
|
1158 $f = _filter_html('<style />', $filter);
|
danielebarchiesi@0
|
1159 $this->assertNoNormalized($f, 'style', 'HTML filter should always remove style tags.');
|
danielebarchiesi@0
|
1160
|
danielebarchiesi@0
|
1161 // Some tags make CSRF attacks easier, let the user take the risk herself.
|
danielebarchiesi@0
|
1162 $f = _filter_html('<img />', $filter);
|
danielebarchiesi@0
|
1163 $this->assertNoNormalized($f, 'img', 'HTML filter should remove img tags on default.');
|
danielebarchiesi@0
|
1164
|
danielebarchiesi@0
|
1165 $f = _filter_html('<input />', $filter);
|
danielebarchiesi@0
|
1166 $this->assertNoNormalized($f, 'img', 'HTML filter should remove input tags on default.');
|
danielebarchiesi@0
|
1167
|
danielebarchiesi@0
|
1168 // Filtering content of some attributes is infeasible, these shouldn't be
|
danielebarchiesi@0
|
1169 // allowed too.
|
danielebarchiesi@0
|
1170 $f = _filter_html('<p style="display: none;" />', $filter);
|
danielebarchiesi@0
|
1171 $this->assertNoNormalized($f, 'style', 'HTML filter should remove style attribute on default.');
|
danielebarchiesi@0
|
1172
|
danielebarchiesi@0
|
1173 $f = _filter_html('<p onerror="alert(0);" />', $filter);
|
danielebarchiesi@0
|
1174 $this->assertNoNormalized($f, 'onerror', 'HTML filter should remove on* attributes on default.');
|
danielebarchiesi@0
|
1175
|
danielebarchiesi@0
|
1176 $f = _filter_html('<code onerror> </code>', $filter);
|
danielebarchiesi@0
|
1177 $this->assertNoNormalized($f, 'onerror', 'HTML filter should remove empty on* attributes on default.');
|
danielebarchiesi@0
|
1178 }
|
danielebarchiesi@0
|
1179
|
danielebarchiesi@0
|
1180 /**
|
danielebarchiesi@0
|
1181 * Tests the spam deterrent.
|
danielebarchiesi@0
|
1182 */
|
danielebarchiesi@0
|
1183 function testNoFollowFilter() {
|
danielebarchiesi@0
|
1184 // Setup dummy filter object.
|
danielebarchiesi@0
|
1185 $filter = new stdClass();
|
danielebarchiesi@0
|
1186 $filter->settings = array(
|
danielebarchiesi@0
|
1187 'allowed_html' => '<a>',
|
danielebarchiesi@0
|
1188 'filter_html_help' => 1,
|
danielebarchiesi@0
|
1189 'filter_html_nofollow' => 1,
|
danielebarchiesi@0
|
1190 );
|
danielebarchiesi@0
|
1191
|
danielebarchiesi@0
|
1192 // Test if the rel="nofollow" attribute is added, even if we try to prevent
|
danielebarchiesi@0
|
1193 // it.
|
danielebarchiesi@0
|
1194 $f = _filter_html('<a href="http://www.example.com/">text</a>', $filter);
|
danielebarchiesi@0
|
1195 $this->assertNormalized($f, 'rel="nofollow"', 'Spam deterrent -- no evasion.');
|
danielebarchiesi@0
|
1196
|
danielebarchiesi@0
|
1197 $f = _filter_html('<A href="http://www.example.com/">text</a>', $filter);
|
danielebarchiesi@0
|
1198 $this->assertNormalized($f, 'rel="nofollow"', 'Spam deterrent evasion -- capital A.');
|
danielebarchiesi@0
|
1199
|
danielebarchiesi@0
|
1200 $f = _filter_html("<a/href=\"http://www.example.com/\">text</a>", $filter);
|
danielebarchiesi@0
|
1201 $this->assertNormalized($f, 'rel="nofollow"', 'Spam deterrent evasion -- non whitespace character after tag name.');
|
danielebarchiesi@0
|
1202
|
danielebarchiesi@0
|
1203 $f = _filter_html("<\0a\0 href=\"http://www.example.com/\">text</a>", $filter);
|
danielebarchiesi@0
|
1204 $this->assertNormalized($f, 'rel="nofollow"', 'Spam deterrent evasion -- some nulls.');
|
danielebarchiesi@0
|
1205
|
danielebarchiesi@0
|
1206 $f = _filter_html('<a href="http://www.example.com/" rel="follow">text</a>', $filter);
|
danielebarchiesi@0
|
1207 $this->assertNoNormalized($f, 'rel="follow"', 'Spam deterrent evasion -- with rel set - rel="follow" removed.');
|
danielebarchiesi@0
|
1208 $this->assertNormalized($f, 'rel="nofollow"', 'Spam deterrent evasion -- with rel set - rel="nofollow" added.');
|
danielebarchiesi@0
|
1209 }
|
danielebarchiesi@0
|
1210
|
danielebarchiesi@0
|
1211 /**
|
danielebarchiesi@0
|
1212 * Tests the loose, admin HTML filter.
|
danielebarchiesi@0
|
1213 */
|
danielebarchiesi@0
|
1214 function testFilterXSSAdmin() {
|
danielebarchiesi@0
|
1215 // DRUPAL-SA-2008-044
|
danielebarchiesi@0
|
1216 $f = filter_xss_admin('<object />');
|
danielebarchiesi@0
|
1217 $this->assertNoNormalized($f, 'object', 'Admin HTML filter -- should not allow object tag.');
|
danielebarchiesi@0
|
1218
|
danielebarchiesi@0
|
1219 $f = filter_xss_admin('<script />');
|
danielebarchiesi@0
|
1220 $this->assertNoNormalized($f, 'script', 'Admin HTML filter -- should not allow script tag.');
|
danielebarchiesi@0
|
1221
|
danielebarchiesi@0
|
1222 $f = filter_xss_admin('<style /><iframe /><frame /><frameset /><meta /><link /><embed /><applet /><param /><layer />');
|
danielebarchiesi@0
|
1223 $this->assertEqual($f, '', 'Admin HTML filter -- should never allow some tags.');
|
danielebarchiesi@0
|
1224 }
|
danielebarchiesi@0
|
1225
|
danielebarchiesi@0
|
1226 /**
|
danielebarchiesi@0
|
1227 * Tests the HTML escaping filter.
|
danielebarchiesi@0
|
1228 *
|
danielebarchiesi@0
|
1229 * check_plain() is not tested here.
|
danielebarchiesi@0
|
1230 */
|
danielebarchiesi@0
|
1231 function testHtmlEscapeFilter() {
|
danielebarchiesi@0
|
1232 // Setup dummy filter object.
|
danielebarchiesi@0
|
1233 $filter = new stdClass();
|
danielebarchiesi@0
|
1234 $filter->callback = '_filter_html_escape';
|
danielebarchiesi@0
|
1235
|
danielebarchiesi@0
|
1236 $tests = array(
|
danielebarchiesi@0
|
1237 " One. <!-- \"comment\" --> Two'.\n<p>Three.</p>\n " => array(
|
danielebarchiesi@0
|
1238 "One. <!-- "comment" --> Two'.\n<p>Three.</p>" => TRUE,
|
danielebarchiesi@0
|
1239 ' One.' => FALSE,
|
danielebarchiesi@0
|
1240 "</p>\n " => FALSE,
|
danielebarchiesi@0
|
1241 ),
|
danielebarchiesi@0
|
1242 );
|
danielebarchiesi@0
|
1243 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
1244 }
|
danielebarchiesi@0
|
1245
|
danielebarchiesi@0
|
1246 /**
|
danielebarchiesi@0
|
1247 * Tests the URL filter.
|
danielebarchiesi@0
|
1248 */
|
danielebarchiesi@0
|
1249 function testUrlFilter() {
|
danielebarchiesi@0
|
1250 // Setup dummy filter object.
|
danielebarchiesi@0
|
1251 $filter = new stdClass();
|
danielebarchiesi@0
|
1252 $filter->callback = '_filter_url';
|
danielebarchiesi@0
|
1253 $filter->settings = array(
|
danielebarchiesi@0
|
1254 'filter_url_length' => 496,
|
danielebarchiesi@0
|
1255 );
|
danielebarchiesi@0
|
1256 // @todo Possible categories:
|
danielebarchiesi@0
|
1257 // - absolute, mail, partial
|
danielebarchiesi@0
|
1258 // - characters/encoding, surrounding markup, security
|
danielebarchiesi@0
|
1259
|
danielebarchiesi@0
|
1260 // Create a e-mail that is too long.
|
danielebarchiesi@0
|
1261 $long_email = str_repeat('a', 254) . '@example.com';
|
danielebarchiesi@0
|
1262 $too_long_email = str_repeat('b', 255) . '@example.com';
|
danielebarchiesi@0
|
1263
|
danielebarchiesi@0
|
1264
|
danielebarchiesi@0
|
1265 // Filter selection/pattern matching.
|
danielebarchiesi@0
|
1266 $tests = array(
|
danielebarchiesi@0
|
1267 // HTTP URLs.
|
danielebarchiesi@0
|
1268 '
|
danielebarchiesi@0
|
1269 http://example.com or www.example.com
|
danielebarchiesi@0
|
1270 ' => array(
|
danielebarchiesi@0
|
1271 '<a href="http://example.com">http://example.com</a>' => TRUE,
|
danielebarchiesi@0
|
1272 '<a href="http://www.example.com">www.example.com</a>' => TRUE,
|
danielebarchiesi@0
|
1273 ),
|
danielebarchiesi@0
|
1274 // MAILTO URLs.
|
danielebarchiesi@0
|
1275 '
|
danielebarchiesi@0
|
1276 person@example.com or mailto:person2@example.com or ' . $long_email . ' but not ' . $too_long_email . '
|
danielebarchiesi@0
|
1277 ' => array(
|
danielebarchiesi@0
|
1278 '<a href="mailto:person@example.com">person@example.com</a>' => TRUE,
|
danielebarchiesi@0
|
1279 '<a href="mailto:person2@example.com">mailto:person2@example.com</a>' => TRUE,
|
danielebarchiesi@0
|
1280 '<a href="mailto:' . $long_email . '">' . $long_email . '</a>' => TRUE,
|
danielebarchiesi@0
|
1281 '<a href="mailto:' . $too_long_email . '">' . $too_long_email . '</a>' => FALSE,
|
danielebarchiesi@0
|
1282 ),
|
danielebarchiesi@0
|
1283 // URI parts and special characters.
|
danielebarchiesi@0
|
1284 '
|
danielebarchiesi@0
|
1285 http://trailingslash.com/ or www.trailingslash.com/
|
danielebarchiesi@0
|
1286 http://host.com/some/path?query=foo&bar[baz]=beer#fragment or www.host.com/some/path?query=foo&bar[baz]=beer#fragment
|
danielebarchiesi@0
|
1287 http://twitter.com/#!/example/status/22376963142324226
|
danielebarchiesi@0
|
1288 ftp://user:pass@ftp.example.com/~home/dir1
|
danielebarchiesi@0
|
1289 sftp://user@nonstandardport:222/dir
|
danielebarchiesi@0
|
1290 ssh://192.168.0.100/srv/git/drupal.git
|
danielebarchiesi@0
|
1291 ' => array(
|
danielebarchiesi@0
|
1292 '<a href="http://trailingslash.com/">http://trailingslash.com/</a>' => TRUE,
|
danielebarchiesi@0
|
1293 '<a href="http://www.trailingslash.com/">www.trailingslash.com/</a>' => TRUE,
|
danielebarchiesi@0
|
1294 '<a href="http://host.com/some/path?query=foo&bar[baz]=beer#fragment">http://host.com/some/path?query=foo&bar[baz]=beer#fragment</a>' => TRUE,
|
danielebarchiesi@0
|
1295 '<a href="http://www.host.com/some/path?query=foo&bar[baz]=beer#fragment">www.host.com/some/path?query=foo&bar[baz]=beer#fragment</a>' => TRUE,
|
danielebarchiesi@0
|
1296 '<a href="http://twitter.com/#!/example/status/22376963142324226">http://twitter.com/#!/example/status/22376963142324226</a>' => TRUE,
|
danielebarchiesi@0
|
1297 '<a href="ftp://user:pass@ftp.example.com/~home/dir1">ftp://user:pass@ftp.example.com/~home/dir1</a>' => TRUE,
|
danielebarchiesi@0
|
1298 '<a href="sftp://user@nonstandardport:222/dir">sftp://user@nonstandardport:222/dir</a>' => TRUE,
|
danielebarchiesi@0
|
1299 '<a href="ssh://192.168.0.100/srv/git/drupal.git">ssh://192.168.0.100/srv/git/drupal.git</a>' => TRUE,
|
danielebarchiesi@0
|
1300 ),
|
danielebarchiesi@0
|
1301 // Encoding.
|
danielebarchiesi@0
|
1302 '
|
danielebarchiesi@0
|
1303 http://ampersand.com/?a=1&b=2
|
danielebarchiesi@0
|
1304 http://encoded.com/?a=1&b=2
|
danielebarchiesi@0
|
1305 ' => array(
|
danielebarchiesi@0
|
1306 '<a href="http://ampersand.com/?a=1&b=2">http://ampersand.com/?a=1&b=2</a>' => TRUE,
|
danielebarchiesi@0
|
1307 '<a href="http://encoded.com/?a=1&b=2">http://encoded.com/?a=1&b=2</a>' => TRUE,
|
danielebarchiesi@0
|
1308 ),
|
danielebarchiesi@0
|
1309 // Domain name length.
|
danielebarchiesi@0
|
1310 '
|
danielebarchiesi@0
|
1311 www.ex.ex or www.example.example or www.toolongdomainexampledomainexampledomainexampledomainexampledomain or
|
danielebarchiesi@0
|
1312 me@me.tv
|
danielebarchiesi@0
|
1313 ' => array(
|
danielebarchiesi@0
|
1314 '<a href="http://www.ex.ex">www.ex.ex</a>' => TRUE,
|
danielebarchiesi@0
|
1315 '<a href="http://www.example.example">www.example.example</a>' => TRUE,
|
danielebarchiesi@0
|
1316 'http://www.toolong' => FALSE,
|
danielebarchiesi@0
|
1317 '<a href="mailto:me@me.tv">me@me.tv</a>' => TRUE,
|
danielebarchiesi@0
|
1318 ),
|
danielebarchiesi@0
|
1319 // Absolute URL protocols.
|
danielebarchiesi@0
|
1320 // The list to test is found in the beginning of _filter_url() at
|
danielebarchiesi@0
|
1321 // $protocols = variable_get('filter_allowed_protocols'... (approx line 1325).
|
danielebarchiesi@0
|
1322 '
|
danielebarchiesi@0
|
1323 https://example.com,
|
danielebarchiesi@0
|
1324 ftp://ftp.example.com,
|
danielebarchiesi@0
|
1325 news://example.net,
|
danielebarchiesi@0
|
1326 telnet://example,
|
danielebarchiesi@0
|
1327 irc://example.host,
|
danielebarchiesi@0
|
1328 ssh://odd.geek,
|
danielebarchiesi@0
|
1329 sftp://secure.host?,
|
danielebarchiesi@0
|
1330 webcal://calendar,
|
danielebarchiesi@0
|
1331 rtsp://127.0.0.1,
|
danielebarchiesi@0
|
1332 not foo://disallowed.com.
|
danielebarchiesi@0
|
1333 ' => array(
|
danielebarchiesi@0
|
1334 'href="https://example.com"' => TRUE,
|
danielebarchiesi@0
|
1335 'href="ftp://ftp.example.com"' => TRUE,
|
danielebarchiesi@0
|
1336 'href="news://example.net"' => TRUE,
|
danielebarchiesi@0
|
1337 'href="telnet://example"' => TRUE,
|
danielebarchiesi@0
|
1338 'href="irc://example.host"' => TRUE,
|
danielebarchiesi@0
|
1339 'href="ssh://odd.geek"' => TRUE,
|
danielebarchiesi@0
|
1340 'href="sftp://secure.host"' => TRUE,
|
danielebarchiesi@0
|
1341 'href="webcal://calendar"' => TRUE,
|
danielebarchiesi@0
|
1342 'href="rtsp://127.0.0.1"' => TRUE,
|
danielebarchiesi@0
|
1343 'href="foo://disallowed.com"' => FALSE,
|
danielebarchiesi@0
|
1344 'not foo://disallowed.com.' => TRUE,
|
danielebarchiesi@0
|
1345 ),
|
danielebarchiesi@0
|
1346 );
|
danielebarchiesi@0
|
1347 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
1348
|
danielebarchiesi@0
|
1349 // Surrounding text/punctuation.
|
danielebarchiesi@0
|
1350 $tests = array(
|
danielebarchiesi@0
|
1351 '
|
danielebarchiesi@0
|
1352 Partial URL with trailing period www.partial.com.
|
danielebarchiesi@0
|
1353 E-mail with trailing comma person@example.com,
|
danielebarchiesi@0
|
1354 Absolute URL with trailing question http://www.absolute.com?
|
danielebarchiesi@0
|
1355 Query string with trailing exclamation www.query.com/index.php?a=!
|
danielebarchiesi@0
|
1356 Partial URL with 3 trailing www.partial.periods...
|
danielebarchiesi@0
|
1357 E-mail with 3 trailing exclamations@example.com!!!
|
danielebarchiesi@0
|
1358 Absolute URL and query string with 2 different punctuation characters (http://www.example.com/q=abc).
|
danielebarchiesi@0
|
1359 ' => array(
|
danielebarchiesi@0
|
1360 'period <a href="http://www.partial.com">www.partial.com</a>.' => TRUE,
|
danielebarchiesi@0
|
1361 'comma <a href="mailto:person@example.com">person@example.com</a>,' => TRUE,
|
danielebarchiesi@0
|
1362 'question <a href="http://www.absolute.com">http://www.absolute.com</a>?' => TRUE,
|
danielebarchiesi@0
|
1363 'exclamation <a href="http://www.query.com/index.php?a=">www.query.com/index.php?a=</a>!' => TRUE,
|
danielebarchiesi@0
|
1364 'trailing <a href="http://www.partial.periods">www.partial.periods</a>...' => TRUE,
|
danielebarchiesi@0
|
1365 'trailing <a href="mailto:exclamations@example.com">exclamations@example.com</a>!!!' => TRUE,
|
danielebarchiesi@0
|
1366 'characters (<a href="http://www.example.com/q=abc">http://www.example.com/q=abc</a>).' => TRUE,
|
danielebarchiesi@0
|
1367 ),
|
danielebarchiesi@0
|
1368 '
|
danielebarchiesi@0
|
1369 (www.parenthesis.com/dir?a=1&b=2#a)
|
danielebarchiesi@0
|
1370 ' => array(
|
danielebarchiesi@0
|
1371 '(<a href="http://www.parenthesis.com/dir?a=1&b=2#a">www.parenthesis.com/dir?a=1&b=2#a</a>)' => TRUE,
|
danielebarchiesi@0
|
1372 ),
|
danielebarchiesi@0
|
1373 );
|
danielebarchiesi@0
|
1374 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
1375
|
danielebarchiesi@0
|
1376 // Surrounding markup.
|
danielebarchiesi@0
|
1377 $tests = array(
|
danielebarchiesi@0
|
1378 '
|
danielebarchiesi@0
|
1379 <p xmlns="www.namespace.com" />
|
danielebarchiesi@0
|
1380 <p xmlns="http://namespace.com">
|
danielebarchiesi@0
|
1381 An <a href="http://example.com" title="Read more at www.example.info...">anchor</a>.
|
danielebarchiesi@0
|
1382 </p>
|
danielebarchiesi@0
|
1383 ' => array(
|
danielebarchiesi@0
|
1384 '<p xmlns="www.namespace.com" />' => TRUE,
|
danielebarchiesi@0
|
1385 '<p xmlns="http://namespace.com">' => TRUE,
|
danielebarchiesi@0
|
1386 'href="http://www.namespace.com"' => FALSE,
|
danielebarchiesi@0
|
1387 'href="http://namespace.com"' => FALSE,
|
danielebarchiesi@0
|
1388 'An <a href="http://example.com" title="Read more at www.example.info...">anchor</a>.' => TRUE,
|
danielebarchiesi@0
|
1389 ),
|
danielebarchiesi@0
|
1390 '
|
danielebarchiesi@0
|
1391 Not <a href="foo">www.relative.com</a> or <a href="http://absolute.com">www.absolute.com</a>
|
danielebarchiesi@0
|
1392 but <strong>http://www.strong.net</strong> or <em>www.emphasis.info</em>
|
danielebarchiesi@0
|
1393 ' => array(
|
danielebarchiesi@0
|
1394 '<a href="foo">www.relative.com</a>' => TRUE,
|
danielebarchiesi@0
|
1395 'href="http://www.relative.com"' => FALSE,
|
danielebarchiesi@0
|
1396 '<a href="http://absolute.com">www.absolute.com</a>' => TRUE,
|
danielebarchiesi@0
|
1397 '<strong><a href="http://www.strong.net">http://www.strong.net</a></strong>' => TRUE,
|
danielebarchiesi@0
|
1398 '<em><a href="http://www.emphasis.info">www.emphasis.info</a></em>' => TRUE,
|
danielebarchiesi@0
|
1399 ),
|
danielebarchiesi@0
|
1400 '
|
danielebarchiesi@0
|
1401 Test <code>using www.example.com the code tag</code>.
|
danielebarchiesi@0
|
1402 ' => array(
|
danielebarchiesi@0
|
1403 'href' => FALSE,
|
danielebarchiesi@0
|
1404 'http' => FALSE,
|
danielebarchiesi@0
|
1405 ),
|
danielebarchiesi@0
|
1406 '
|
danielebarchiesi@0
|
1407 Intro.
|
danielebarchiesi@0
|
1408 <blockquote>
|
danielebarchiesi@0
|
1409 Quoted text linking to www.example.com, written by person@example.com, originating from http://origin.example.com. <code>@see www.usage.example.com or <em>www.example.info</em> bla bla</code>.
|
danielebarchiesi@0
|
1410 </blockquote>
|
danielebarchiesi@0
|
1411
|
danielebarchiesi@0
|
1412 Outro.
|
danielebarchiesi@0
|
1413 ' => array(
|
danielebarchiesi@0
|
1414 'href="http://www.example.com"' => TRUE,
|
danielebarchiesi@0
|
1415 'href="mailto:person@example.com"' => TRUE,
|
danielebarchiesi@0
|
1416 'href="http://origin.example.com"' => TRUE,
|
danielebarchiesi@0
|
1417 'http://www.usage.example.com' => FALSE,
|
danielebarchiesi@0
|
1418 'http://www.example.info' => FALSE,
|
danielebarchiesi@0
|
1419 'Intro.' => TRUE,
|
danielebarchiesi@0
|
1420 'Outro.' => TRUE,
|
danielebarchiesi@0
|
1421 ),
|
danielebarchiesi@0
|
1422 '
|
danielebarchiesi@0
|
1423 Unknown tag <x>containing x and www.example.com</x>? And a tag <pooh>beginning with p and containing www.example.pooh with p?</pooh>
|
danielebarchiesi@0
|
1424 ' => array(
|
danielebarchiesi@0
|
1425 'href="http://www.example.com"' => TRUE,
|
danielebarchiesi@0
|
1426 'href="http://www.example.pooh"' => TRUE,
|
danielebarchiesi@0
|
1427 ),
|
danielebarchiesi@0
|
1428 '
|
danielebarchiesi@0
|
1429 <p>Test <br/>: This is a www.example17.com example <strong>with</strong> various http://www.example18.com tags. *<br/>
|
danielebarchiesi@0
|
1430 It is important www.example19.com to *<br/>test different URLs and http://www.example20.com in the same paragraph. *<br>
|
danielebarchiesi@0
|
1431 HTML www.example21.com soup by person@example22.com can litererally http://www.example23.com contain *img*<img> anything. Just a www.example24.com with http://www.example25.com thrown in. www.example26.com from person@example27.com with extra http://www.example28.com.
|
danielebarchiesi@0
|
1432 ' => array(
|
danielebarchiesi@0
|
1433 'href="http://www.example17.com"' => TRUE,
|
danielebarchiesi@0
|
1434 'href="http://www.example18.com"' => TRUE,
|
danielebarchiesi@0
|
1435 'href="http://www.example19.com"' => TRUE,
|
danielebarchiesi@0
|
1436 'href="http://www.example20.com"' => TRUE,
|
danielebarchiesi@0
|
1437 'href="http://www.example21.com"' => TRUE,
|
danielebarchiesi@0
|
1438 'href="mailto:person@example22.com"' => TRUE,
|
danielebarchiesi@0
|
1439 'href="http://www.example23.com"' => TRUE,
|
danielebarchiesi@0
|
1440 'href="http://www.example24.com"' => TRUE,
|
danielebarchiesi@0
|
1441 'href="http://www.example25.com"' => TRUE,
|
danielebarchiesi@0
|
1442 'href="http://www.example26.com"' => TRUE,
|
danielebarchiesi@0
|
1443 'href="mailto:person@example27.com"' => TRUE,
|
danielebarchiesi@0
|
1444 'href="http://www.example28.com"' => TRUE,
|
danielebarchiesi@0
|
1445 ),
|
danielebarchiesi@0
|
1446 '
|
danielebarchiesi@0
|
1447 <script>
|
danielebarchiesi@0
|
1448 <!--
|
danielebarchiesi@0
|
1449 // @see www.example.com
|
danielebarchiesi@0
|
1450 var exampleurl = "http://example.net";
|
danielebarchiesi@0
|
1451 -->
|
danielebarchiesi@0
|
1452 <!--//--><![CDATA[//><!--
|
danielebarchiesi@0
|
1453 // @see www.example.com
|
danielebarchiesi@0
|
1454 var exampleurl = "http://example.net";
|
danielebarchiesi@0
|
1455 //--><!]]>
|
danielebarchiesi@0
|
1456 </script>
|
danielebarchiesi@0
|
1457 ' => array(
|
danielebarchiesi@0
|
1458 'href="http://www.example.com"' => FALSE,
|
danielebarchiesi@0
|
1459 'href="http://example.net"' => FALSE,
|
danielebarchiesi@0
|
1460 ),
|
danielebarchiesi@0
|
1461 '
|
danielebarchiesi@0
|
1462 <style>body {
|
danielebarchiesi@0
|
1463 background: url(http://example.com/pixel.gif);
|
danielebarchiesi@0
|
1464 }</style>
|
danielebarchiesi@0
|
1465 ' => array(
|
danielebarchiesi@0
|
1466 'href' => FALSE,
|
danielebarchiesi@0
|
1467 ),
|
danielebarchiesi@0
|
1468 '
|
danielebarchiesi@0
|
1469 <!-- Skip any URLs like www.example.com in comments -->
|
danielebarchiesi@0
|
1470 ' => array(
|
danielebarchiesi@0
|
1471 'href' => FALSE,
|
danielebarchiesi@0
|
1472 ),
|
danielebarchiesi@0
|
1473 '
|
danielebarchiesi@0
|
1474 <!-- Skip any URLs like
|
danielebarchiesi@0
|
1475 www.example.com with a newline in comments -->
|
danielebarchiesi@0
|
1476 ' => array(
|
danielebarchiesi@0
|
1477 'href' => FALSE,
|
danielebarchiesi@0
|
1478 ),
|
danielebarchiesi@0
|
1479 '
|
danielebarchiesi@0
|
1480 <!-- Skip any URLs like www.comment.com in comments. <p>Also ignore http://commented.out/markup.</p> -->
|
danielebarchiesi@0
|
1481 ' => array(
|
danielebarchiesi@0
|
1482 'href' => FALSE,
|
danielebarchiesi@0
|
1483 ),
|
danielebarchiesi@0
|
1484 '
|
danielebarchiesi@0
|
1485 <dl>
|
danielebarchiesi@0
|
1486 <dt>www.example.com</dt>
|
danielebarchiesi@0
|
1487 <dd>http://example.com</dd>
|
danielebarchiesi@0
|
1488 <dd>person@example.com</dd>
|
danielebarchiesi@0
|
1489 <dt>Check www.example.net</dt>
|
danielebarchiesi@0
|
1490 <dd>Some text around http://www.example.info by person@example.info?</dd>
|
danielebarchiesi@0
|
1491 </dl>
|
danielebarchiesi@0
|
1492 ' => array(
|
danielebarchiesi@0
|
1493 'href="http://www.example.com"' => TRUE,
|
danielebarchiesi@0
|
1494 'href="http://example.com"' => TRUE,
|
danielebarchiesi@0
|
1495 'href="mailto:person@example.com"' => TRUE,
|
danielebarchiesi@0
|
1496 'href="http://www.example.net"' => TRUE,
|
danielebarchiesi@0
|
1497 'href="http://www.example.info"' => TRUE,
|
danielebarchiesi@0
|
1498 'href="mailto:person@example.info"' => TRUE,
|
danielebarchiesi@0
|
1499 ),
|
danielebarchiesi@0
|
1500 '
|
danielebarchiesi@0
|
1501 <div>www.div.com</div>
|
danielebarchiesi@0
|
1502 <ul>
|
danielebarchiesi@0
|
1503 <li>http://listitem.com</li>
|
danielebarchiesi@0
|
1504 <li class="odd">www.class.listitem.com</li>
|
danielebarchiesi@0
|
1505 </ul>
|
danielebarchiesi@0
|
1506 ' => array(
|
danielebarchiesi@0
|
1507 '<div><a href="http://www.div.com">www.div.com</a></div>' => TRUE,
|
danielebarchiesi@0
|
1508 '<li><a href="http://listitem.com">http://listitem.com</a></li>' => TRUE,
|
danielebarchiesi@0
|
1509 '<li class="odd"><a href="http://www.class.listitem.com">www.class.listitem.com</a></li>' => TRUE,
|
danielebarchiesi@0
|
1510 ),
|
danielebarchiesi@0
|
1511 );
|
danielebarchiesi@0
|
1512 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
1513
|
danielebarchiesi@0
|
1514 // URL trimming.
|
danielebarchiesi@0
|
1515 $filter->settings['filter_url_length'] = 20;
|
danielebarchiesi@0
|
1516 $tests = array(
|
danielebarchiesi@0
|
1517 'www.trimmed.com/d/ff.ext?a=1&b=2#a1' => array(
|
danielebarchiesi@0
|
1518 '<a href="http://www.trimmed.com/d/ff.ext?a=1&b=2#a1">www.trimmed.com/d/ff...</a>' => TRUE,
|
danielebarchiesi@0
|
1519 ),
|
danielebarchiesi@0
|
1520 );
|
danielebarchiesi@0
|
1521 $this->assertFilteredString($filter, $tests);
|
danielebarchiesi@0
|
1522 }
|
danielebarchiesi@0
|
1523
|
danielebarchiesi@0
|
1524 /**
|
danielebarchiesi@0
|
1525 * Asserts multiple filter output expectations for multiple input strings.
|
danielebarchiesi@0
|
1526 *
|
danielebarchiesi@0
|
1527 * @param $filter
|
danielebarchiesi@0
|
1528 * A input filter object.
|
danielebarchiesi@0
|
1529 * @param $tests
|
danielebarchiesi@0
|
1530 * An associative array, whereas each key is an arbitrary input string and
|
danielebarchiesi@0
|
1531 * each value is again an associative array whose keys are filter output
|
danielebarchiesi@0
|
1532 * strings and whose values are Booleans indicating whether the output is
|
danielebarchiesi@0
|
1533 * expected or not.
|
danielebarchiesi@0
|
1534 *
|
danielebarchiesi@0
|
1535 * For example:
|
danielebarchiesi@0
|
1536 * @code
|
danielebarchiesi@0
|
1537 * $tests = array(
|
danielebarchiesi@0
|
1538 * 'Input string' => array(
|
danielebarchiesi@0
|
1539 * '<p>Input string</p>' => TRUE,
|
danielebarchiesi@0
|
1540 * 'Input string<br' => FALSE,
|
danielebarchiesi@0
|
1541 * ),
|
danielebarchiesi@0
|
1542 * );
|
danielebarchiesi@0
|
1543 * @endcode
|
danielebarchiesi@0
|
1544 */
|
danielebarchiesi@0
|
1545 function assertFilteredString($filter, $tests) {
|
danielebarchiesi@0
|
1546 foreach ($tests as $source => $tasks) {
|
danielebarchiesi@0
|
1547 $function = $filter->callback;
|
danielebarchiesi@0
|
1548 $result = $function($source, $filter);
|
danielebarchiesi@0
|
1549 foreach ($tasks as $value => $is_expected) {
|
danielebarchiesi@0
|
1550 // Not using assertIdentical, since combination with strpos() is hard to grok.
|
danielebarchiesi@0
|
1551 if ($is_expected) {
|
danielebarchiesi@0
|
1552 $success = $this->assertTrue(strpos($result, $value) !== FALSE, format_string('@source: @value found.', array(
|
danielebarchiesi@0
|
1553 '@source' => var_export($source, TRUE),
|
danielebarchiesi@0
|
1554 '@value' => var_export($value, TRUE),
|
danielebarchiesi@0
|
1555 )));
|
danielebarchiesi@0
|
1556 }
|
danielebarchiesi@0
|
1557 else {
|
danielebarchiesi@0
|
1558 $success = $this->assertTrue(strpos($result, $value) === FALSE, format_string('@source: @value not found.', array(
|
danielebarchiesi@0
|
1559 '@source' => var_export($source, TRUE),
|
danielebarchiesi@0
|
1560 '@value' => var_export($value, TRUE),
|
danielebarchiesi@0
|
1561 )));
|
danielebarchiesi@0
|
1562 }
|
danielebarchiesi@0
|
1563 if (!$success) {
|
danielebarchiesi@0
|
1564 $this->verbose('Source:<pre>' . check_plain(var_export($source, TRUE)) . '</pre>'
|
danielebarchiesi@0
|
1565 . '<hr />' . 'Result:<pre>' . check_plain(var_export($result, TRUE)) . '</pre>'
|
danielebarchiesi@0
|
1566 . '<hr />' . ($is_expected ? 'Expected:' : 'Not expected:')
|
danielebarchiesi@0
|
1567 . '<pre>' . check_plain(var_export($value, TRUE)) . '</pre>'
|
danielebarchiesi@0
|
1568 );
|
danielebarchiesi@0
|
1569 }
|
danielebarchiesi@0
|
1570 }
|
danielebarchiesi@0
|
1571 }
|
danielebarchiesi@0
|
1572 }
|
danielebarchiesi@0
|
1573
|
danielebarchiesi@0
|
1574 /**
|
danielebarchiesi@0
|
1575 * Tests URL filter on longer content.
|
danielebarchiesi@0
|
1576 *
|
danielebarchiesi@0
|
1577 * Filters based on regular expressions should also be tested with a more
|
danielebarchiesi@0
|
1578 * complex content than just isolated test lines.
|
danielebarchiesi@0
|
1579 * The most common errors are:
|
danielebarchiesi@0
|
1580 * - accidental '*' (greedy) match instead of '*?' (minimal) match.
|
danielebarchiesi@0
|
1581 * - only matching first occurrence instead of all.
|
danielebarchiesi@0
|
1582 * - newlines not matching '.*'.
|
danielebarchiesi@0
|
1583 *
|
danielebarchiesi@0
|
1584 * This test covers:
|
danielebarchiesi@0
|
1585 * - Document with multiple newlines and paragraphs (two newlines).
|
danielebarchiesi@0
|
1586 * - Mix of several HTML tags, invalid non-HTML tags, tags to ignore and HTML
|
danielebarchiesi@0
|
1587 * comments.
|
danielebarchiesi@0
|
1588 * - Empty HTML tags (BR, IMG).
|
danielebarchiesi@0
|
1589 * - Mix of absolute and partial URLs, and e-mail addresses in one content.
|
danielebarchiesi@0
|
1590 */
|
danielebarchiesi@0
|
1591 function testUrlFilterContent() {
|
danielebarchiesi@0
|
1592 // Setup dummy filter object.
|
danielebarchiesi@0
|
1593 $filter = new stdClass();
|
danielebarchiesi@0
|
1594 $filter->settings = array(
|
danielebarchiesi@0
|
1595 'filter_url_length' => 496,
|
danielebarchiesi@0
|
1596 );
|
danielebarchiesi@0
|
1597 $path = drupal_get_path('module', 'filter') . '/tests';
|
danielebarchiesi@0
|
1598
|
danielebarchiesi@0
|
1599 $input = file_get_contents($path . '/filter.url-input.txt');
|
danielebarchiesi@0
|
1600 $expected = file_get_contents($path . '/filter.url-output.txt');
|
danielebarchiesi@0
|
1601 $result = _filter_url($input, $filter);
|
danielebarchiesi@0
|
1602 $this->assertIdentical($result, $expected, 'Complex HTML document was correctly processed.');
|
danielebarchiesi@0
|
1603 }
|
danielebarchiesi@0
|
1604
|
danielebarchiesi@0
|
1605 /**
|
danielebarchiesi@0
|
1606 * Tests the HTML corrector filter.
|
danielebarchiesi@0
|
1607 *
|
danielebarchiesi@0
|
1608 * @todo This test could really use some validity checking function.
|
danielebarchiesi@0
|
1609 */
|
danielebarchiesi@0
|
1610 function testHtmlCorrectorFilter() {
|
danielebarchiesi@0
|
1611 // Tag closing.
|
danielebarchiesi@0
|
1612 $f = _filter_htmlcorrector('<p>text');
|
danielebarchiesi@0
|
1613 $this->assertEqual($f, '<p>text</p>', 'HTML corrector -- tag closing at the end of input.');
|
danielebarchiesi@0
|
1614
|
danielebarchiesi@0
|
1615 $f = _filter_htmlcorrector('<p>text<p><p>text');
|
danielebarchiesi@0
|
1616 $this->assertEqual($f, '<p>text</p><p></p><p>text</p>', 'HTML corrector -- tag closing.');
|
danielebarchiesi@0
|
1617
|
danielebarchiesi@0
|
1618 $f = _filter_htmlcorrector("<ul><li>e1<li>e2");
|
danielebarchiesi@0
|
1619 $this->assertEqual($f, "<ul><li>e1</li><li>e2</li></ul>", 'HTML corrector -- unclosed list tags.');
|
danielebarchiesi@0
|
1620
|
danielebarchiesi@0
|
1621 $f = _filter_htmlcorrector('<div id="d">content');
|
danielebarchiesi@0
|
1622 $this->assertEqual($f, '<div id="d">content</div>', 'HTML corrector -- unclosed tag with attribute.');
|
danielebarchiesi@0
|
1623
|
danielebarchiesi@0
|
1624 // XHTML slash for empty elements.
|
danielebarchiesi@0
|
1625 $f = _filter_htmlcorrector('<hr><br>');
|
danielebarchiesi@0
|
1626 $this->assertEqual($f, '<hr /><br />', 'HTML corrector -- XHTML closing slash.');
|
danielebarchiesi@0
|
1627
|
danielebarchiesi@0
|
1628 $f = _filter_htmlcorrector('<P>test</P>');
|
danielebarchiesi@0
|
1629 $this->assertEqual($f, '<p>test</p>', 'HTML corrector -- Convert uppercased tags to proper lowercased ones.');
|
danielebarchiesi@0
|
1630
|
danielebarchiesi@0
|
1631 $f = _filter_htmlcorrector('<P>test</p>');
|
danielebarchiesi@0
|
1632 $this->assertEqual($f, '<p>test</p>', 'HTML corrector -- Convert uppercased tags to proper lowercased ones.');
|
danielebarchiesi@0
|
1633
|
danielebarchiesi@0
|
1634 $f = _filter_htmlcorrector('test<hr />');
|
danielebarchiesi@0
|
1635 $this->assertEqual($f, 'test<hr />', 'HTML corrector -- Let proper XHTML pass through.');
|
danielebarchiesi@0
|
1636
|
danielebarchiesi@0
|
1637 $f = _filter_htmlcorrector('test<hr/>');
|
danielebarchiesi@0
|
1638 $this->assertEqual($f, 'test<hr />', 'HTML corrector -- Let proper XHTML pass through, but ensure there is a single space before the closing slash.');
|
danielebarchiesi@0
|
1639
|
danielebarchiesi@0
|
1640 $f = _filter_htmlcorrector('test<hr />');
|
danielebarchiesi@0
|
1641 $this->assertEqual($f, 'test<hr />', 'HTML corrector -- Let proper XHTML pass through, but ensure there are not too many spaces before the closing slash.');
|
danielebarchiesi@0
|
1642
|
danielebarchiesi@0
|
1643 $f = _filter_htmlcorrector('<span class="test" />');
|
danielebarchiesi@0
|
1644 $this->assertEqual($f, '<span class="test"></span>', 'HTML corrector -- Convert XHTML that is properly formed but that would not be compatible with typical HTML user agents.');
|
danielebarchiesi@0
|
1645
|
danielebarchiesi@0
|
1646 $f = _filter_htmlcorrector('test1<br class="test">test2');
|
danielebarchiesi@0
|
1647 $this->assertEqual($f, 'test1<br class="test" />test2', 'HTML corrector -- Automatically close single tags.');
|
danielebarchiesi@0
|
1648
|
danielebarchiesi@0
|
1649 $f = _filter_htmlcorrector('line1<hr>line2');
|
danielebarchiesi@0
|
1650 $this->assertEqual($f, 'line1<hr />line2', 'HTML corrector -- Automatically close single tags.');
|
danielebarchiesi@0
|
1651
|
danielebarchiesi@0
|
1652 $f = _filter_htmlcorrector('line1<HR>line2');
|
danielebarchiesi@0
|
1653 $this->assertEqual($f, 'line1<hr />line2', 'HTML corrector -- Automatically close single tags.');
|
danielebarchiesi@0
|
1654
|
danielebarchiesi@0
|
1655 $f = _filter_htmlcorrector('<img src="http://example.com/test.jpg">test</img>');
|
danielebarchiesi@0
|
1656 $this->assertEqual($f, '<img src="http://example.com/test.jpg" />test', 'HTML corrector -- Automatically close single tags.');
|
danielebarchiesi@0
|
1657
|
danielebarchiesi@0
|
1658 $f = _filter_htmlcorrector('<br></br>');
|
danielebarchiesi@0
|
1659 $this->assertEqual($f, '<br />', "HTML corrector -- Transform empty tags to a single closed tag if the tag's content model is EMPTY.");
|
danielebarchiesi@0
|
1660
|
danielebarchiesi@0
|
1661 $f = _filter_htmlcorrector('<div></div>');
|
danielebarchiesi@0
|
1662 $this->assertEqual($f, '<div></div>', "HTML corrector -- Do not transform empty tags to a single closed tag if the tag's content model is not EMPTY.");
|
danielebarchiesi@0
|
1663
|
danielebarchiesi@0
|
1664 $f = _filter_htmlcorrector('<p>line1<br/><hr/>line2</p>');
|
danielebarchiesi@0
|
1665 $this->assertEqual($f, '<p>line1<br /></p><hr />line2', 'HTML corrector -- Move non-inline elements outside of inline containers.');
|
danielebarchiesi@0
|
1666
|
danielebarchiesi@0
|
1667 $f = _filter_htmlcorrector('<p>line1<div>line2</div></p>');
|
danielebarchiesi@0
|
1668 $this->assertEqual($f, '<p>line1</p><div>line2</div>', 'HTML corrector -- Move non-inline elements outside of inline containers.');
|
danielebarchiesi@0
|
1669
|
danielebarchiesi@0
|
1670 $f = _filter_htmlcorrector('<p>test<p>test</p>\n');
|
danielebarchiesi@0
|
1671 $this->assertEqual($f, '<p>test</p><p>test</p>\n', 'HTML corrector -- Auto-close improperly nested tags.');
|
danielebarchiesi@0
|
1672
|
danielebarchiesi@0
|
1673 $f = _filter_htmlcorrector('<p>Line1<br><STRONG>bold stuff</b>');
|
danielebarchiesi@0
|
1674 $this->assertEqual($f, '<p>Line1<br /><strong>bold stuff</strong></p>', 'HTML corrector -- Properly close unclosed tags, and remove useless closing tags.');
|
danielebarchiesi@0
|
1675
|
danielebarchiesi@0
|
1676 $f = _filter_htmlcorrector('test <!-- this is a comment -->');
|
danielebarchiesi@0
|
1677 $this->assertEqual($f, 'test <!-- this is a comment -->', 'HTML corrector -- Do not touch HTML comments.');
|
danielebarchiesi@0
|
1678
|
danielebarchiesi@0
|
1679 $f = _filter_htmlcorrector('test <!--this is a comment-->');
|
danielebarchiesi@0
|
1680 $this->assertEqual($f, 'test <!--this is a comment-->', 'HTML corrector -- Do not touch HTML comments.');
|
danielebarchiesi@0
|
1681
|
danielebarchiesi@0
|
1682 $f = _filter_htmlcorrector('test <!-- comment <p>another
|
danielebarchiesi@0
|
1683 <strong>multiple</strong> line
|
danielebarchiesi@0
|
1684 comment</p> -->');
|
danielebarchiesi@0
|
1685 $this->assertEqual($f, 'test <!-- comment <p>another
|
danielebarchiesi@0
|
1686 <strong>multiple</strong> line
|
danielebarchiesi@0
|
1687 comment</p> -->', 'HTML corrector -- Do not touch HTML comments.');
|
danielebarchiesi@0
|
1688
|
danielebarchiesi@0
|
1689 $f = _filter_htmlcorrector('test <!-- comment <p>another comment</p> -->');
|
danielebarchiesi@0
|
1690 $this->assertEqual($f, 'test <!-- comment <p>another comment</p> -->', 'HTML corrector -- Do not touch HTML comments.');
|
danielebarchiesi@0
|
1691
|
danielebarchiesi@0
|
1692 $f = _filter_htmlcorrector('test <!--break-->');
|
danielebarchiesi@0
|
1693 $this->assertEqual($f, 'test <!--break-->', 'HTML corrector -- Do not touch HTML comments.');
|
danielebarchiesi@0
|
1694
|
danielebarchiesi@0
|
1695 $f = _filter_htmlcorrector('<p>test\n</p>\n');
|
danielebarchiesi@0
|
1696 $this->assertEqual($f, '<p>test\n</p>\n', 'HTML corrector -- New-lines are accepted and kept as-is.');
|
danielebarchiesi@0
|
1697
|
danielebarchiesi@0
|
1698 $f = _filter_htmlcorrector('<p>دروبال');
|
danielebarchiesi@0
|
1699 $this->assertEqual($f, '<p>دروبال</p>', 'HTML corrector -- Encoding is correctly kept.');
|
danielebarchiesi@0
|
1700
|
danielebarchiesi@0
|
1701 $f = _filter_htmlcorrector('<script type="text/javascript">alert("test")</script>');
|
danielebarchiesi@0
|
1702 $this->assertEqual($f, '<script type="text/javascript">
|
danielebarchiesi@0
|
1703 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1704 alert("test")
|
danielebarchiesi@0
|
1705 //--><!]]>
|
danielebarchiesi@0
|
1706 </script>', 'HTML corrector -- CDATA added to script element');
|
danielebarchiesi@0
|
1707
|
danielebarchiesi@0
|
1708 $f = _filter_htmlcorrector('<p><script type="text/javascript">alert("test")</script></p>');
|
danielebarchiesi@0
|
1709 $this->assertEqual($f, '<p><script type="text/javascript">
|
danielebarchiesi@0
|
1710 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1711 alert("test")
|
danielebarchiesi@0
|
1712 //--><!]]>
|
danielebarchiesi@0
|
1713 </script></p>', 'HTML corrector -- CDATA added to a nested script element');
|
danielebarchiesi@0
|
1714
|
danielebarchiesi@0
|
1715 $f = _filter_htmlcorrector('<p><style> /* Styling */ body {color:red}</style></p>');
|
danielebarchiesi@0
|
1716 $this->assertEqual($f, '<p><style>
|
danielebarchiesi@0
|
1717 <!--/*--><![CDATA[/* ><!--*/
|
danielebarchiesi@0
|
1718 /* Styling */ body {color:red}
|
danielebarchiesi@0
|
1719 /*--><!]]>*/
|
danielebarchiesi@0
|
1720 </style></p>', 'HTML corrector -- CDATA added to a style element.');
|
danielebarchiesi@0
|
1721
|
danielebarchiesi@0
|
1722 $filtered_data = _filter_htmlcorrector('<p><style>
|
danielebarchiesi@0
|
1723 /*<![CDATA[*/
|
danielebarchiesi@0
|
1724 /* Styling */
|
danielebarchiesi@0
|
1725 body {color:red}
|
danielebarchiesi@0
|
1726 /*]]>*/
|
danielebarchiesi@0
|
1727 </style></p>');
|
danielebarchiesi@0
|
1728 $this->assertEqual($filtered_data, '<p><style>
|
danielebarchiesi@0
|
1729 <!--/*--><![CDATA[/* ><!--*/
|
danielebarchiesi@0
|
1730
|
danielebarchiesi@0
|
1731 /*<![CDATA[*/
|
danielebarchiesi@0
|
1732 /* Styling */
|
danielebarchiesi@0
|
1733 body {color:red}
|
danielebarchiesi@0
|
1734 /*]]]]><![CDATA[>*/
|
danielebarchiesi@0
|
1735
|
danielebarchiesi@0
|
1736 /*--><!]]>*/
|
danielebarchiesi@0
|
1737 </style></p>',
|
danielebarchiesi@0
|
1738 format_string('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '/*<![CDATA[*/'))
|
danielebarchiesi@0
|
1739 );
|
danielebarchiesi@0
|
1740
|
danielebarchiesi@0
|
1741 $filtered_data = _filter_htmlcorrector('<p><style>
|
danielebarchiesi@0
|
1742 <!--/*--><![CDATA[/* ><!--*/
|
danielebarchiesi@0
|
1743 /* Styling */
|
danielebarchiesi@0
|
1744 body {color:red}
|
danielebarchiesi@0
|
1745 /*--><!]]>*/
|
danielebarchiesi@0
|
1746 </style></p>');
|
danielebarchiesi@0
|
1747 $this->assertEqual($filtered_data, '<p><style>
|
danielebarchiesi@0
|
1748 <!--/*--><![CDATA[/* ><!--*/
|
danielebarchiesi@0
|
1749
|
danielebarchiesi@0
|
1750 <!--/*--><![CDATA[/* ><!--*/
|
danielebarchiesi@0
|
1751 /* Styling */
|
danielebarchiesi@0
|
1752 body {color:red}
|
danielebarchiesi@0
|
1753 /*--><!]]]]><![CDATA[>*/
|
danielebarchiesi@0
|
1754
|
danielebarchiesi@0
|
1755 /*--><!]]>*/
|
danielebarchiesi@0
|
1756 </style></p>',
|
danielebarchiesi@0
|
1757 format_string('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '<!--/*--><![CDATA[/* ><!--*/'))
|
danielebarchiesi@0
|
1758 );
|
danielebarchiesi@0
|
1759
|
danielebarchiesi@0
|
1760 $filtered_data = _filter_htmlcorrector('<p><script type="text/javascript">
|
danielebarchiesi@0
|
1761 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1762 alert("test");
|
danielebarchiesi@0
|
1763 //--><!]]>
|
danielebarchiesi@0
|
1764 </script></p>');
|
danielebarchiesi@0
|
1765 $this->assertEqual($filtered_data, '<p><script type="text/javascript">
|
danielebarchiesi@0
|
1766 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1767
|
danielebarchiesi@0
|
1768 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1769 alert("test");
|
danielebarchiesi@0
|
1770 //--><!]]]]><![CDATA[>
|
danielebarchiesi@0
|
1771
|
danielebarchiesi@0
|
1772 //--><!]]>
|
danielebarchiesi@0
|
1773 </script></p>',
|
danielebarchiesi@0
|
1774 format_string('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '<!--//--><![CDATA[// ><!--'))
|
danielebarchiesi@0
|
1775 );
|
danielebarchiesi@0
|
1776
|
danielebarchiesi@0
|
1777 $filtered_data = _filter_htmlcorrector('<p><script type="text/javascript">
|
danielebarchiesi@0
|
1778 // <![CDATA[
|
danielebarchiesi@0
|
1779 alert("test");
|
danielebarchiesi@0
|
1780 // ]]>
|
danielebarchiesi@0
|
1781 </script></p>');
|
danielebarchiesi@0
|
1782 $this->assertEqual($filtered_data, '<p><script type="text/javascript">
|
danielebarchiesi@0
|
1783 <!--//--><![CDATA[// ><!--
|
danielebarchiesi@0
|
1784
|
danielebarchiesi@0
|
1785 // <![CDATA[
|
danielebarchiesi@0
|
1786 alert("test");
|
danielebarchiesi@0
|
1787 // ]]]]><![CDATA[>
|
danielebarchiesi@0
|
1788
|
danielebarchiesi@0
|
1789 //--><!]]>
|
danielebarchiesi@0
|
1790 </script></p>',
|
danielebarchiesi@0
|
1791 format_string('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '// <![CDATA['))
|
danielebarchiesi@0
|
1792 );
|
danielebarchiesi@0
|
1793
|
danielebarchiesi@0
|
1794 }
|
danielebarchiesi@0
|
1795
|
danielebarchiesi@0
|
1796 /**
|
danielebarchiesi@0
|
1797 * Asserts that a text transformed to lowercase with HTML entities decoded does contains a given string.
|
danielebarchiesi@0
|
1798 *
|
danielebarchiesi@0
|
1799 * Otherwise fails the test with a given message, similar to all the
|
danielebarchiesi@0
|
1800 * SimpleTest assert* functions.
|
danielebarchiesi@0
|
1801 *
|
danielebarchiesi@0
|
1802 * Note that this does not remove nulls, new lines and other characters that
|
danielebarchiesi@0
|
1803 * could be used to obscure a tag or an attribute name.
|
danielebarchiesi@0
|
1804 *
|
danielebarchiesi@0
|
1805 * @param $haystack
|
danielebarchiesi@0
|
1806 * Text to look in.
|
danielebarchiesi@0
|
1807 * @param $needle
|
danielebarchiesi@0
|
1808 * Lowercase, plain text to look for.
|
danielebarchiesi@0
|
1809 * @param $message
|
danielebarchiesi@0
|
1810 * (optional) Message to display if failed. Defaults to an empty string.
|
danielebarchiesi@0
|
1811 * @param $group
|
danielebarchiesi@0
|
1812 * (optional) The group this message belongs to. Defaults to 'Other'.
|
danielebarchiesi@0
|
1813 * @return
|
danielebarchiesi@0
|
1814 * TRUE on pass, FALSE on fail.
|
danielebarchiesi@0
|
1815 */
|
danielebarchiesi@0
|
1816 function assertNormalized($haystack, $needle, $message = '', $group = 'Other') {
|
danielebarchiesi@0
|
1817 return $this->assertTrue(strpos(strtolower(decode_entities($haystack)), $needle) !== FALSE, $message, $group);
|
danielebarchiesi@0
|
1818 }
|
danielebarchiesi@0
|
1819
|
danielebarchiesi@0
|
1820 /**
|
danielebarchiesi@0
|
1821 * Asserts that text transformed to lowercase with HTML entities decoded does not contain a given string.
|
danielebarchiesi@0
|
1822 *
|
danielebarchiesi@0
|
1823 * Otherwise fails the test with a given message, similar to all the
|
danielebarchiesi@0
|
1824 * SimpleTest assert* functions.
|
danielebarchiesi@0
|
1825 *
|
danielebarchiesi@0
|
1826 * Note that this does not remove nulls, new lines, and other character that
|
danielebarchiesi@0
|
1827 * could be used to obscure a tag or an attribute name.
|
danielebarchiesi@0
|
1828 *
|
danielebarchiesi@0
|
1829 * @param $haystack
|
danielebarchiesi@0
|
1830 * Text to look in.
|
danielebarchiesi@0
|
1831 * @param $needle
|
danielebarchiesi@0
|
1832 * Lowercase, plain text to look for.
|
danielebarchiesi@0
|
1833 * @param $message
|
danielebarchiesi@0
|
1834 * (optional) Message to display if failed. Defaults to an empty string.
|
danielebarchiesi@0
|
1835 * @param $group
|
danielebarchiesi@0
|
1836 * (optional) The group this message belongs to. Defaults to 'Other'.
|
danielebarchiesi@0
|
1837 * @return
|
danielebarchiesi@0
|
1838 * TRUE on pass, FALSE on fail.
|
danielebarchiesi@0
|
1839 */
|
danielebarchiesi@0
|
1840 function assertNoNormalized($haystack, $needle, $message = '', $group = 'Other') {
|
danielebarchiesi@0
|
1841 return $this->assertTrue(strpos(strtolower(decode_entities($haystack)), $needle) === FALSE, $message, $group);
|
danielebarchiesi@0
|
1842 }
|
danielebarchiesi@0
|
1843 }
|
danielebarchiesi@0
|
1844
|
danielebarchiesi@0
|
1845 /**
|
danielebarchiesi@0
|
1846 * Tests for Filter's hook invocations.
|
danielebarchiesi@0
|
1847 */
|
danielebarchiesi@0
|
1848 class FilterHooksTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
1849 public static function getInfo() {
|
danielebarchiesi@0
|
1850 return array(
|
danielebarchiesi@0
|
1851 'name' => 'Filter format hooks',
|
danielebarchiesi@0
|
1852 'description' => 'Test hooks for text formats insert/update/disable.',
|
danielebarchiesi@0
|
1853 'group' => 'Filter',
|
danielebarchiesi@0
|
1854 );
|
danielebarchiesi@0
|
1855 }
|
danielebarchiesi@0
|
1856
|
danielebarchiesi@0
|
1857 function setUp() {
|
danielebarchiesi@0
|
1858 parent::setUp('block', 'filter_test');
|
danielebarchiesi@0
|
1859 $admin_user = $this->drupalCreateUser(array('administer filters', 'administer blocks'));
|
danielebarchiesi@0
|
1860 $this->drupalLogin($admin_user);
|
danielebarchiesi@0
|
1861 }
|
danielebarchiesi@0
|
1862
|
danielebarchiesi@0
|
1863 /**
|
danielebarchiesi@0
|
1864 * Tests hooks on format management.
|
danielebarchiesi@0
|
1865 *
|
danielebarchiesi@0
|
1866 * Tests that hooks run correctly on creating, editing, and deleting a text
|
danielebarchiesi@0
|
1867 * format.
|
danielebarchiesi@0
|
1868 */
|
danielebarchiesi@0
|
1869 function testFilterHooks() {
|
danielebarchiesi@0
|
1870 // Add a text format.
|
danielebarchiesi@0
|
1871 $name = $this->randomName();
|
danielebarchiesi@0
|
1872 $edit = array();
|
danielebarchiesi@0
|
1873 $edit['format'] = drupal_strtolower($this->randomName());
|
danielebarchiesi@0
|
1874 $edit['name'] = $name;
|
danielebarchiesi@0
|
1875 $edit['roles[' . DRUPAL_ANONYMOUS_RID . ']'] = 1;
|
danielebarchiesi@0
|
1876 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
|
danielebarchiesi@0
|
1877 $this->assertRaw(t('Added text format %format.', array('%format' => $name)), 'New format created.');
|
danielebarchiesi@0
|
1878 $this->assertText('hook_filter_format_insert invoked.', 'hook_filter_format_insert was invoked.');
|
danielebarchiesi@0
|
1879
|
danielebarchiesi@0
|
1880 $format_id = $edit['format'];
|
danielebarchiesi@0
|
1881
|
danielebarchiesi@0
|
1882 // Update text format.
|
danielebarchiesi@0
|
1883 $edit = array();
|
danielebarchiesi@0
|
1884 $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = 1;
|
danielebarchiesi@0
|
1885 $this->drupalPost('admin/config/content/formats/' . $format_id, $edit, t('Save configuration'));
|
danielebarchiesi@0
|
1886 $this->assertRaw(t('The text format %format has been updated.', array('%format' => $name)), 'Format successfully updated.');
|
danielebarchiesi@0
|
1887 $this->assertText('hook_filter_format_update invoked.', 'hook_filter_format_update() was invoked.');
|
danielebarchiesi@0
|
1888
|
danielebarchiesi@0
|
1889 // Add a new custom block.
|
danielebarchiesi@0
|
1890 $custom_block = array();
|
danielebarchiesi@0
|
1891 $custom_block['info'] = $this->randomName(8);
|
danielebarchiesi@0
|
1892 $custom_block['title'] = $this->randomName(8);
|
danielebarchiesi@0
|
1893 $custom_block['body[value]'] = $this->randomName(32);
|
danielebarchiesi@0
|
1894 // Use the format created.
|
danielebarchiesi@0
|
1895 $custom_block['body[format]'] = $format_id;
|
danielebarchiesi@0
|
1896 $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
|
danielebarchiesi@0
|
1897 $this->assertText(t('The block has been created.'), 'New block successfully created.');
|
danielebarchiesi@0
|
1898
|
danielebarchiesi@0
|
1899 // Verify the new block is in the database.
|
danielebarchiesi@0
|
1900 $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
|
danielebarchiesi@0
|
1901 $this->assertNotNull($bid, 'New block found in database');
|
danielebarchiesi@0
|
1902
|
danielebarchiesi@0
|
1903 // Disable the text format.
|
danielebarchiesi@0
|
1904 $this->drupalPost('admin/config/content/formats/' . $format_id . '/disable', array(), t('Disable'));
|
danielebarchiesi@0
|
1905 $this->assertRaw(t('Disabled text format %format.', array('%format' => $name)), 'Format successfully disabled.');
|
danielebarchiesi@0
|
1906 $this->assertText('hook_filter_format_disable invoked.', 'hook_filter_format_disable() was invoked.');
|
danielebarchiesi@0
|
1907 }
|
danielebarchiesi@0
|
1908 }
|
danielebarchiesi@0
|
1909
|
danielebarchiesi@0
|
1910 /**
|
danielebarchiesi@0
|
1911 * Tests filter settings.
|
danielebarchiesi@0
|
1912 */
|
danielebarchiesi@0
|
1913 class FilterSettingsTestCase extends DrupalWebTestCase {
|
danielebarchiesi@0
|
1914 /**
|
danielebarchiesi@0
|
1915 * The installation profile to use with this test class.
|
danielebarchiesi@0
|
1916 *
|
danielebarchiesi@0
|
1917 * @var string
|
danielebarchiesi@0
|
1918 */
|
danielebarchiesi@0
|
1919 protected $profile = 'testing';
|
danielebarchiesi@0
|
1920
|
danielebarchiesi@0
|
1921 public static function getInfo() {
|
danielebarchiesi@0
|
1922 return array(
|
danielebarchiesi@0
|
1923 'name' => 'Filter settings',
|
danielebarchiesi@0
|
1924 'description' => 'Tests filter settings.',
|
danielebarchiesi@0
|
1925 'group' => 'Filter',
|
danielebarchiesi@0
|
1926 );
|
danielebarchiesi@0
|
1927 }
|
danielebarchiesi@0
|
1928
|
danielebarchiesi@0
|
1929 /**
|
danielebarchiesi@0
|
1930 * Tests explicit and implicit default settings for filters.
|
danielebarchiesi@0
|
1931 */
|
danielebarchiesi@0
|
1932 function testFilterDefaults() {
|
danielebarchiesi@0
|
1933 $filter_info = filter_filter_info();
|
danielebarchiesi@0
|
1934 $filters = array_fill_keys(array_keys($filter_info), array());
|
danielebarchiesi@0
|
1935
|
danielebarchiesi@0
|
1936 // Create text format using filter default settings.
|
danielebarchiesi@0
|
1937 $filter_defaults_format = (object) array(
|
danielebarchiesi@0
|
1938 'format' => 'filter_defaults',
|
danielebarchiesi@0
|
1939 'name' => 'Filter defaults',
|
danielebarchiesi@0
|
1940 'filters' => $filters,
|
danielebarchiesi@0
|
1941 );
|
danielebarchiesi@0
|
1942 filter_format_save($filter_defaults_format);
|
danielebarchiesi@0
|
1943
|
danielebarchiesi@0
|
1944 // Verify that default weights defined in hook_filter_info() were applied.
|
danielebarchiesi@0
|
1945 $saved_settings = array();
|
danielebarchiesi@0
|
1946 foreach ($filter_defaults_format->filters as $name => $settings) {
|
danielebarchiesi@0
|
1947 $expected_weight = (isset($filter_info[$name]['weight']) ? $filter_info[$name]['weight'] : 0);
|
danielebarchiesi@0
|
1948 $this->assertEqual($settings['weight'], $expected_weight, format_string('@name filter weight %saved equals %default', array(
|
danielebarchiesi@0
|
1949 '@name' => $name,
|
danielebarchiesi@0
|
1950 '%saved' => $settings['weight'],
|
danielebarchiesi@0
|
1951 '%default' => $expected_weight,
|
danielebarchiesi@0
|
1952 )));
|
danielebarchiesi@0
|
1953 $saved_settings[$name]['weight'] = $expected_weight;
|
danielebarchiesi@0
|
1954 }
|
danielebarchiesi@0
|
1955
|
danielebarchiesi@0
|
1956 // Re-save the text format.
|
danielebarchiesi@0
|
1957 filter_format_save($filter_defaults_format);
|
danielebarchiesi@0
|
1958 // Reload it from scratch.
|
danielebarchiesi@0
|
1959 filter_formats_reset();
|
danielebarchiesi@0
|
1960 $filter_defaults_format = filter_format_load($filter_defaults_format->format);
|
danielebarchiesi@0
|
1961 $filter_defaults_format->filters = filter_list_format($filter_defaults_format->format);
|
danielebarchiesi@0
|
1962
|
danielebarchiesi@0
|
1963 // Verify that saved filter settings have not been changed.
|
danielebarchiesi@0
|
1964 foreach ($filter_defaults_format->filters as $name => $settings) {
|
danielebarchiesi@0
|
1965 $this->assertEqual($settings->weight, $saved_settings[$name]['weight'], format_string('@name filter weight %saved equals %previous', array(
|
danielebarchiesi@0
|
1966 '@name' => $name,
|
danielebarchiesi@0
|
1967 '%saved' => $settings->weight,
|
danielebarchiesi@0
|
1968 '%previous' => $saved_settings[$name]['weight'],
|
danielebarchiesi@0
|
1969 )));
|
danielebarchiesi@0
|
1970 }
|
danielebarchiesi@0
|
1971 }
|
danielebarchiesi@0
|
1972 }
|