commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / modules / field / modules / text / text.test
1 <?php
2
3 /**
4 * @file
5 * Tests for text.module.
6 */
7
8 class TextFieldTestCase extends DrupalWebTestCase {
9 protected $instance;
10 protected $admin_user;
11 protected $web_user;
12
13 public static function getInfo() {
14 return array(
15 'name' => 'Text field',
16 'description' => "Test the creation of text fields.",
17 'group' => 'Field types'
18 );
19 }
20
21 function setUp() {
22 parent::setUp('field_test');
23
24 $this->admin_user = $this->drupalCreateUser(array('administer filters'));
25 $this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
26 $this->drupalLogin($this->web_user);
27 }
28
29 // Test fields.
30
31 /**
32 * Test text field validation.
33 */
34 function testTextFieldValidation() {
35 // Create a field with settings to validate.
36 $max_length = 3;
37 $this->field = array(
38 'field_name' => drupal_strtolower($this->randomName()),
39 'type' => 'text',
40 'settings' => array(
41 'max_length' => $max_length,
42 )
43 );
44 field_create_field($this->field);
45 $this->instance = array(
46 'field_name' => $this->field['field_name'],
47 'entity_type' => 'test_entity',
48 'bundle' => 'test_bundle',
49 'widget' => array(
50 'type' => 'text_textfield',
51 ),
52 'display' => array(
53 'default' => array(
54 'type' => 'text_default',
55 ),
56 ),
57 );
58 field_create_instance($this->instance);
59 // Test valid and invalid values with field_attach_validate().
60 $entity = field_test_create_stub_entity();
61 $langcode = LANGUAGE_NONE;
62 for ($i = 0; $i <= $max_length + 2; $i++) {
63 $entity->{$this->field['field_name']}[$langcode][0]['value'] = str_repeat('x', $i);
64 try {
65 field_attach_validate('test_entity', $entity);
66 $this->assertTrue($i <= $max_length, "Length $i does not cause validation error when max_length is $max_length");
67 }
68 catch (FieldValidationException $e) {
69 $this->assertTrue($i > $max_length, "Length $i causes validation error when max_length is $max_length");
70 }
71 }
72 }
73
74 /**
75 * Test widgets.
76 */
77 function testTextfieldWidgets() {
78 $this->_testTextfieldWidgets('text', 'text_textfield');
79 $this->_testTextfieldWidgets('text_long', 'text_textarea');
80 }
81
82 /**
83 * Helper function for testTextfieldWidgets().
84 */
85 function _testTextfieldWidgets($field_type, $widget_type) {
86 // Setup a field and instance
87 $entity_type = 'test_entity';
88 $this->field_name = drupal_strtolower($this->randomName());
89 $this->field = array('field_name' => $this->field_name, 'type' => $field_type);
90 field_create_field($this->field);
91 $this->instance = array(
92 'field_name' => $this->field_name,
93 'entity_type' => 'test_entity',
94 'bundle' => 'test_bundle',
95 'label' => $this->randomName() . '_label',
96 'settings' => array(
97 'text_processing' => TRUE,
98 ),
99 'widget' => array(
100 'type' => $widget_type,
101 ),
102 'display' => array(
103 'full' => array(
104 'type' => 'text_default',
105 ),
106 ),
107 );
108 field_create_instance($this->instance);
109 $langcode = LANGUAGE_NONE;
110
111 // Display creation form.
112 $this->drupalGet('test-entity/add/test-bundle');
113 $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
114 $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', 'Format selector is not displayed');
115
116 // Submit with some value.
117 $value = $this->randomName();
118 $edit = array(
119 "{$this->field_name}[$langcode][0][value]" => $value,
120 );
121 $this->drupalPost(NULL, $edit, t('Save'));
122 preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
123 $id = $match[1];
124 $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
125
126 // Display the entity.
127 $entity = field_test_entity_test_load($id);
128 $entity->content = field_attach_view($entity_type, $entity, 'full');
129 $this->content = drupal_render($entity->content);
130 $this->assertText($value, 'Filtered tags are not displayed');
131 }
132
133 /**
134 * Test widgets + 'formatted_text' setting.
135 */
136 function testTextfieldWidgetsFormatted() {
137 $this->_testTextfieldWidgetsFormatted('text', 'text_textfield');
138 $this->_testTextfieldWidgetsFormatted('text_long', 'text_textarea');
139 }
140
141 /**
142 * Helper function for testTextfieldWidgetsFormatted().
143 */
144 function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
145 // Setup a field and instance
146 $entity_type = 'test_entity';
147 $this->field_name = drupal_strtolower($this->randomName());
148 $this->field = array('field_name' => $this->field_name, 'type' => $field_type);
149 field_create_field($this->field);
150 $this->instance = array(
151 'field_name' => $this->field_name,
152 'entity_type' => 'test_entity',
153 'bundle' => 'test_bundle',
154 'label' => $this->randomName() . '_label',
155 'settings' => array(
156 'text_processing' => TRUE,
157 ),
158 'widget' => array(
159 'type' => $widget_type,
160 ),
161 'display' => array(
162 'full' => array(
163 'type' => 'text_default',
164 ),
165 ),
166 );
167 field_create_instance($this->instance);
168 $langcode = LANGUAGE_NONE;
169
170 // Disable all text formats besides the plain text fallback format.
171 $this->drupalLogin($this->admin_user);
172 foreach (filter_formats() as $format) {
173 if ($format->format != filter_fallback_format()) {
174 $this->drupalPost('admin/config/content/formats/' . $format->format . '/disable', array(), t('Disable'));
175 }
176 }
177 $this->drupalLogin($this->web_user);
178
179 // Display the creation form. Since the user only has access to one format,
180 // no format selector will be displayed.
181 $this->drupalGet('test-entity/add/test-bundle');
182 $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed');
183 $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '', 'Format selector is not displayed');
184
185 // Submit with data that should be filtered.
186 $value = '<em>' . $this->randomName() . '</em>';
187 $edit = array(
188 "{$this->field_name}[$langcode][0][value]" => $value,
189 );
190 $this->drupalPost(NULL, $edit, t('Save'));
191 preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
192 $id = $match[1];
193 $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created');
194
195 // Display the entity.
196 $entity = field_test_entity_test_load($id);
197 $entity->content = field_attach_view($entity_type, $entity, 'full');
198 $this->content = drupal_render($entity->content);
199 $this->assertNoRaw($value, 'HTML tags are not displayed.');
200 $this->assertRaw(check_plain($value), 'Escaped HTML is displayed correctly.');
201
202 // Create a new text format that does not escape HTML, and grant the user
203 // access to it.
204 $this->drupalLogin($this->admin_user);
205 $edit = array(
206 'format' => drupal_strtolower($this->randomName()),
207 'name' => $this->randomName(),
208 );
209 $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
210 filter_formats_reset();
211 $this->checkPermissions(array(), TRUE);
212 $format = filter_format_load($edit['format']);
213 $format_id = $format->format;
214 $permission = filter_permission_name($format);
215 $rid = max(array_keys($this->web_user->roles));
216 user_role_grant_permissions($rid, array($permission));
217 $this->drupalLogin($this->web_user);
218
219 // Display edition form.
220 // We should now have a 'text format' selector.
221 $this->drupalGet('test-entity/manage/' . $id . '/edit');
222 $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", NULL, 'Widget is displayed');
223 $this->assertFieldByName("{$this->field_name}[$langcode][0][format]", NULL, 'Format selector is displayed');
224
225 // Edit and change the text format to the new one that was created.
226 $edit = array(
227 "{$this->field_name}[$langcode][0][format]" => $format_id,
228 );
229 $this->drupalPost(NULL, $edit, t('Save'));
230 $this->assertRaw(t('test_entity @id has been updated.', array('@id' => $id)), 'Entity was updated');
231
232 // Display the entity.
233 $entity = field_test_entity_test_load($id);
234 $entity->content = field_attach_view($entity_type, $entity, 'full');
235 $this->content = drupal_render($entity->content);
236 $this->assertRaw($value, 'Value is displayed unfiltered');
237 }
238 }
239
240 class TextSummaryTestCase extends DrupalWebTestCase {
241 public static function getInfo() {
242 return array(
243 'name' => 'Text summary',
244 'description' => 'Test text_summary() with different strings and lengths.',
245 'group' => 'Field types',
246 );
247 }
248
249 function setUp() {
250 parent::setUp();
251 $this->article_creator = $this->drupalCreateUser(array('create article content', 'edit own article content'));
252 }
253
254 /**
255 * Tests an edge case where the first sentence is a question and
256 * subsequent sentences are not. This edge case is documented at
257 * http://drupal.org/node/180425.
258 */
259 function testFirstSentenceQuestion() {
260 $text = 'A question? A sentence. Another sentence.';
261 $expected = 'A question? A sentence.';
262 $this->callTextSummary($text, $expected, NULL, 30);
263 }
264
265 /**
266 * Test summary with long example.
267 */
268 function testLongSentence() {
269 $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . // 125
270 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . // 108
271 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' . // 103
272 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; // 110
273 $expected = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' .
274 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' .
275 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.';
276 // First three sentences add up to: 336, so add one for space and then 3 to get half-way into next word.
277 $this->callTextSummary($text, $expected, NULL, 340);
278 }
279
280 /**
281 * Test various summary length edge cases.
282 */
283 function testLength() {
284 // This string tests a number of edge cases.
285 $text = "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>";
286
287 // The summaries we expect text_summary() to return when $size is the index
288 // of each array item.
289 // Using no text format:
290 $expected = array(
291 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
292 "<",
293 "<p",
294 "<p>",
295 "<p>\n",
296 "<p>\nH",
297 "<p>\nHi",
298 "<p>\nHi\n",
299 "<p>\nHi\n<",
300 "<p>\nHi\n</",
301 "<p>\nHi\n</p",
302 "<p>\nHi\n</p>",
303 "<p>\nHi\n</p>",
304 "<p>\nHi\n</p>",
305 "<p>\nHi\n</p>",
306 "<p>\nHi\n</p>",
307 "<p>\nHi\n</p>",
308 "<p>\nHi\n</p>",
309 "<p>\nHi\n</p>",
310 "<p>\nHi\n</p>",
311 "<p>\nHi\n</p>",
312 "<p>\nHi\n</p>",
313 "<p>\nHi\n</p>",
314 "<p>\nHi\n</p>",
315 "<p>\nHi\n</p>",
316 "<p>\nHi\n</p>",
317 "<p>\nHi\n</p>",
318 "<p>\nHi\n</p>",
319 "<p>\nHi\n</p>",
320 "<p>\nHi\n</p>",
321 "<p>\nHi\n</p>",
322 "<p>\nHi\n</p>",
323 "<p>\nHi\n</p>",
324 "<p>\nHi\n</p>",
325 "<p>\nHi\n</p>",
326 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
327 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
328 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
329 );
330
331 // And using a text format WITH the line-break and htmlcorrector filters.
332 $expected_lb = array(
333 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
334 "",
335 "<p></p>",
336 "<p></p>",
337 "<p></p>",
338 "<p></p>",
339 "<p></p>",
340 "<p>\nHi</p>",
341 "<p>\nHi</p>",
342 "<p>\nHi</p>",
343 "<p>\nHi</p>",
344 "<p>\nHi\n</p>",
345 "<p>\nHi\n</p>",
346 "<p>\nHi\n</p>",
347 "<p>\nHi\n</p>",
348 "<p>\nHi\n</p>",
349 "<p>\nHi\n</p>",
350 "<p>\nHi\n</p>",
351 "<p>\nHi\n</p>",
352 "<p>\nHi\n</p>",
353 "<p>\nHi\n</p>",
354 "<p>\nHi\n</p>",
355 "<p>\nHi\n</p>",
356 "<p>\nHi\n</p>",
357 "<p>\nHi\n</p>",
358 "<p>\nHi\n</p>",
359 "<p>\nHi\n</p>",
360 "<p>\nHi\n</p>",
361 "<p>\nHi\n</p>",
362 "<p>\nHi\n</p>",
363 "<p>\nHi\n</p>",
364 "<p>\nHi\n</p>",
365 "<p>\nHi\n</p>",
366 "<p>\nHi\n</p>",
367 "<p>\nHi\n</p>",
368 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
369 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
370 "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
371 );
372
373 // Test text_summary() for different sizes.
374 for ($i = 0; $i <= 37; $i++) {
375 $this->callTextSummary($text, $expected[$i], NULL, $i);
376 $this->callTextSummary($text, $expected_lb[$i], 'plain_text', $i);
377 $this->callTextSummary($text, $expected_lb[$i], 'filtered_html', $i);
378 }
379 }
380
381 /**
382 * Calls text_summary() and asserts that the expected teaser is returned.
383 */
384 function callTextSummary($text, $expected, $format = NULL, $size = NULL) {
385 $summary = text_summary($text, $format, $size);
386 $this->assertIdentical($summary, $expected, format_string('Generated summary "@summary" matches expected "@expected".', array('@summary' => $summary, '@expected' => $expected)));
387 }
388
389 /**
390 * Test sending only summary.
391 */
392 function testOnlyTextSummary() {
393 // Login as article creator.
394 $this->drupalLogin($this->article_creator);
395 // Create article with summary but empty body.
396 $summary = $this->randomName();
397 $edit = array(
398 "title" => $this->randomName(),
399 "body[und][0][summary]" => $summary,
400 );
401 $this->drupalPost('node/add/article', $edit, t('Save'));
402 $node = $this->drupalGetNodeByTitle($edit['title']);
403
404 $this->assertIdentical($node->body['und'][0]['summary'], $summary, 'Article with with summary and no body has been submitted.');
405 }
406 }
407
408 class TextTranslationTestCase extends DrupalWebTestCase {
409 public static function getInfo() {
410 return array(
411 'name' => 'Text translation',
412 'description' => 'Check if the text field is correctly prepared for translation.',
413 'group' => 'Field types',
414 );
415 }
416
417 function setUp() {
418 parent::setUp('locale', 'translation');
419
420 $full_html_format = filter_format_load('full_html');
421 $this->format = $full_html_format->format;
422 $this->admin = $this->drupalCreateUser(array(
423 'administer languages',
424 'administer content types',
425 'access administration pages',
426 'bypass node access',
427 'administer fields',
428 filter_permission_name($full_html_format),
429 ));
430 $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content'));
431
432 // Enable an additional language.
433 $this->drupalLogin($this->admin);
434 $edit = array('langcode' => 'fr');
435 $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
436
437 // Set "Article" content type to use multilingual support with translation.
438 $edit = array('language_content_type' => 2);
439 $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
440 $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Article content type has been updated.');
441 }
442
443 /**
444 * Test that a plaintext textfield widget is correctly populated.
445 */
446 function testTextField() {
447 // Disable text processing for body.
448 $edit = array('instance[settings][text_processing]' => 0);
449 $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
450
451 // Login as translator.
452 $this->drupalLogin($this->translator);
453
454 // Create content.
455 $langcode = LANGUAGE_NONE;
456 $body = $this->randomName();
457 $edit = array(
458 "title" => $this->randomName(),
459 "language" => 'en',
460 "body[$langcode][0][value]" => $body,
461 );
462
463 // Translate the article in french.
464 $this->drupalPost('node/add/article', $edit, t('Save'));
465 $node = $this->drupalGetNodeByTitle($edit['title']);
466 $this->drupalGet("node/$node->nid/translate");
467 $this->clickLink(t('add translation'));
468 $this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, 'The textfield widget is populated.');
469 }
470
471 /**
472 * Check that user that does not have access the field format cannot see the
473 * source value when creating a translation.
474 */
475 function testTextFieldFormatted() {
476 // Make node body multiple.
477 $edit = array('field[cardinality]' => -1);
478 $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
479 $this->drupalGet('node/add/article');
480 $this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.');
481
482 $body = array(
483 $this->randomName(),
484 $this->randomName(),
485 );
486
487 // Create an article with the first body input format set to "Full HTML".
488 $title = $this->randomName();
489 $edit = array(
490 'title' => $title,
491 'language' => 'en',
492 );
493 $this->drupalPost('node/add/article', $edit, t('Save'));
494
495 // Populate the body field: the first item gets the "Full HTML" input
496 // format, the second one "Filtered HTML".
497 $formats = array('full_html', 'filtered_html');
498 $langcode = LANGUAGE_NONE;
499 foreach ($body as $delta => $value) {
500 $edit = array(
501 "body[$langcode][$delta][value]" => $value,
502 "body[$langcode][$delta][format]" => array_shift($formats),
503 );
504 $this->drupalPost('node/1/edit', $edit, t('Save'));
505 $this->assertText($body[$delta], format_string('The body field with delta @delta has been saved.', array('@delta' => $delta)));
506 }
507
508 // Login as translator.
509 $this->drupalLogin($this->translator);
510
511 // Translate the article in french.
512 $node = $this->drupalGetNodeByTitle($title);
513 $this->drupalGet("node/$node->nid/translate");
514 $this->clickLink(t('add translation'));
515 $this->assertNoText($body[0], format_string('The body field with delta @delta is hidden.', array('@delta' => 0)));
516 $this->assertText($body[1], format_string('The body field with delta @delta is shown.', array('@delta' => 1)));
517 }
518 }