'Text field', 'description' => "Test the creation of text fields.", 'group' => 'Field types' ); } function setUp() { parent::setUp('field_test'); $this->admin_user = $this->drupalCreateUser(array('administer filters')); $this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content')); $this->drupalLogin($this->web_user); } // Test fields. /** * Test text field validation. */ function testTextFieldValidation() { // Create a field with settings to validate. $max_length = 3; $this->field = array( 'field_name' => drupal_strtolower($this->randomName()), 'type' => 'text', 'settings' => array( 'max_length' => $max_length, ) ); field_create_field($this->field); $this->instance = array( 'field_name' => $this->field['field_name'], 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'default' => array( 'type' => 'text_default', ), ), ); field_create_instance($this->instance); // Test valid and invalid values with field_attach_validate(). $entity = field_test_create_stub_entity(); $langcode = LANGUAGE_NONE; for ($i = 0; $i <= $max_length + 2; $i++) { $entity->{$this->field['field_name']}[$langcode][0]['value'] = str_repeat('x', $i); try { field_attach_validate('test_entity', $entity); $this->assertTrue($i <= $max_length, "Length $i does not cause validation error when max_length is $max_length"); } catch (FieldValidationException $e) { $this->assertTrue($i > $max_length, "Length $i causes validation error when max_length is $max_length"); } } } /** * Test widgets. */ function testTextfieldWidgets() { $this->_testTextfieldWidgets('text', 'text_textfield'); $this->_testTextfieldWidgets('text_long', 'text_textarea'); } /** * Helper function for testTextfieldWidgets(). */ function _testTextfieldWidgets($field_type, $widget_type) { // Setup a field and instance $entity_type = 'test_entity'; $this->field_name = drupal_strtolower($this->randomName()); $this->field = array('field_name' => $this->field_name, 'type' => $field_type); field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'label' => $this->randomName() . '_label', 'settings' => array( 'text_processing' => TRUE, ), 'widget' => array( 'type' => $widget_type, ), 'display' => array( 'full' => array( 'type' => 'text_default', ), ), ); field_create_instance($this->instance); $langcode = LANGUAGE_NONE; // Display creation form. $this->drupalGet('test-entity/add/test-bundle'); $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed'); $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '1', 'Format selector is not displayed'); // Submit with some value. $value = $this->randomName(); $edit = array( "{$this->field_name}[$langcode][0][value]" => $value, ); $this->drupalPost(NULL, $edit, t('Save')); preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match); $id = $match[1]; $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created'); // Display the entity. $entity = field_test_entity_test_load($id); $entity->content = field_attach_view($entity_type, $entity, 'full'); $this->content = drupal_render($entity->content); $this->assertText($value, 'Filtered tags are not displayed'); } /** * Test widgets + 'formatted_text' setting. */ function testTextfieldWidgetsFormatted() { $this->_testTextfieldWidgetsFormatted('text', 'text_textfield'); $this->_testTextfieldWidgetsFormatted('text_long', 'text_textarea'); } /** * Helper function for testTextfieldWidgetsFormatted(). */ function _testTextfieldWidgetsFormatted($field_type, $widget_type) { // Setup a field and instance $entity_type = 'test_entity'; $this->field_name = drupal_strtolower($this->randomName()); $this->field = array('field_name' => $this->field_name, 'type' => $field_type); field_create_field($this->field); $this->instance = array( 'field_name' => $this->field_name, 'entity_type' => 'test_entity', 'bundle' => 'test_bundle', 'label' => $this->randomName() . '_label', 'settings' => array( 'text_processing' => TRUE, ), 'widget' => array( 'type' => $widget_type, ), 'display' => array( 'full' => array( 'type' => 'text_default', ), ), ); field_create_instance($this->instance); $langcode = LANGUAGE_NONE; // Disable all text formats besides the plain text fallback format. $this->drupalLogin($this->admin_user); foreach (filter_formats() as $format) { if ($format->format != filter_fallback_format()) { $this->drupalPost('admin/config/content/formats/' . $format->format . '/disable', array(), t('Disable')); } } $this->drupalLogin($this->web_user); // Display the creation form. Since the user only has access to one format, // no format selector will be displayed. $this->drupalGet('test-entity/add/test-bundle'); $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", '', 'Widget is displayed'); $this->assertNoFieldByName("{$this->field_name}[$langcode][0][format]", '', 'Format selector is not displayed'); // Submit with data that should be filtered. $value = '' . $this->randomName() . ''; $edit = array( "{$this->field_name}[$langcode][0][value]" => $value, ); $this->drupalPost(NULL, $edit, t('Save')); preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match); $id = $match[1]; $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created'); // Display the entity. $entity = field_test_entity_test_load($id); $entity->content = field_attach_view($entity_type, $entity, 'full'); $this->content = drupal_render($entity->content); $this->assertNoRaw($value, 'HTML tags are not displayed.'); $this->assertRaw(check_plain($value), 'Escaped HTML is displayed correctly.'); // Create a new text format that does not escape HTML, and grant the user // access to it. $this->drupalLogin($this->admin_user); $edit = array( 'format' => drupal_strtolower($this->randomName()), 'name' => $this->randomName(), ); $this->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration')); filter_formats_reset(); $this->checkPermissions(array(), TRUE); $format = filter_format_load($edit['format']); $format_id = $format->format; $permission = filter_permission_name($format); $rid = max(array_keys($this->web_user->roles)); user_role_grant_permissions($rid, array($permission)); $this->drupalLogin($this->web_user); // Display edition form. // We should now have a 'text format' selector. $this->drupalGet('test-entity/manage/' . $id . '/edit'); $this->assertFieldByName("{$this->field_name}[$langcode][0][value]", NULL, 'Widget is displayed'); $this->assertFieldByName("{$this->field_name}[$langcode][0][format]", NULL, 'Format selector is displayed'); // Edit and change the text format to the new one that was created. $edit = array( "{$this->field_name}[$langcode][0][format]" => $format_id, ); $this->drupalPost(NULL, $edit, t('Save')); $this->assertRaw(t('test_entity @id has been updated.', array('@id' => $id)), 'Entity was updated'); // Display the entity. $entity = field_test_entity_test_load($id); $entity->content = field_attach_view($entity_type, $entity, 'full'); $this->content = drupal_render($entity->content); $this->assertRaw($value, 'Value is displayed unfiltered'); } } class TextSummaryTestCase extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => 'Text summary', 'description' => 'Test text_summary() with different strings and lengths.', 'group' => 'Field types', ); } function setUp() { parent::setUp(); $this->article_creator = $this->drupalCreateUser(array('create article content', 'edit own article content')); } /** * Tests an edge case where the first sentence is a question and * subsequent sentences are not. This edge case is documented at * http://drupal.org/node/180425. */ function testFirstSentenceQuestion() { $text = 'A question? A sentence. Another sentence.'; $expected = 'A question? A sentence.'; $this->callTextSummary($text, $expected, NULL, 30); } /** * Test summary with long example. */ function testLongSentence() { $text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . // 125 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . // 108 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ' . // 103 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; // 110 $expected = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ' . 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ' . 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.'; // First three sentences add up to: 336, so add one for space and then 3 to get half-way into next word. $this->callTextSummary($text, $expected, NULL, 340); } /** * Test various summary length edge cases. */ function testLength() { // This string tests a number of edge cases. $text = "

\nHi\n

\n

\nfolks\n
\n!\n

"; // The summaries we expect text_summary() to return when $size is the index // of each array item. // Using no text format: $expected = array( "

\nHi\n

\n

\nfolks\n
\n!\n

", "<", "", "

\n", "

\nH", "

\nHi", "

\nHi\n", "

\nHi\n<", "

\nHi\n\nHi\n\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", ); // And using a text format WITH the line-break and htmlcorrector filters. $expected_lb = array( "

\nHi\n

\n

\nfolks\n
\n!\n

", "", "

", "

", "

", "

", "

", "

\nHi

", "

\nHi

", "

\nHi

", "

\nHi

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", "

\nHi\n

\n

\nfolks\n
\n!\n

", ); // Test text_summary() for different sizes. for ($i = 0; $i <= 37; $i++) { $this->callTextSummary($text, $expected[$i], NULL, $i); $this->callTextSummary($text, $expected_lb[$i], 'plain_text', $i); $this->callTextSummary($text, $expected_lb[$i], 'filtered_html', $i); } } /** * Calls text_summary() and asserts that the expected teaser is returned. */ function callTextSummary($text, $expected, $format = NULL, $size = NULL) { $summary = text_summary($text, $format, $size); $this->assertIdentical($summary, $expected, format_string('Generated summary "@summary" matches expected "@expected".', array('@summary' => $summary, '@expected' => $expected))); } /** * Test sending only summary. */ function testOnlyTextSummary() { // Login as article creator. $this->drupalLogin($this->article_creator); // Create article with summary but empty body. $summary = $this->randomName(); $edit = array( "title" => $this->randomName(), "body[und][0][summary]" => $summary, ); $this->drupalPost('node/add/article', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title']); $this->assertIdentical($node->body['und'][0]['summary'], $summary, 'Article with with summary and no body has been submitted.'); } } class TextTranslationTestCase extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => 'Text translation', 'description' => 'Check if the text field is correctly prepared for translation.', 'group' => 'Field types', ); } function setUp() { parent::setUp('locale', 'translation'); $full_html_format = filter_format_load('full_html'); $this->format = $full_html_format->format; $this->admin = $this->drupalCreateUser(array( 'administer languages', 'administer content types', 'access administration pages', 'bypass node access', 'administer fields', filter_permission_name($full_html_format), )); $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content')); // Enable an additional language. $this->drupalLogin($this->admin); $edit = array('langcode' => 'fr'); $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); // Set "Article" content type to use multilingual support with translation. $edit = array('language_content_type' => 2); $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type')); $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Article content type has been updated.'); } /** * Test that a plaintext textfield widget is correctly populated. */ function testTextField() { // Disable text processing for body. $edit = array('instance[settings][text_processing]' => 0); $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings')); // Login as translator. $this->drupalLogin($this->translator); // Create content. $langcode = LANGUAGE_NONE; $body = $this->randomName(); $edit = array( "title" => $this->randomName(), "language" => 'en', "body[$langcode][0][value]" => $body, ); // Translate the article in french. $this->drupalPost('node/add/article', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title']); $this->drupalGet("node/$node->nid/translate"); $this->clickLink(t('add translation')); $this->assertFieldByXPath("//textarea[@name='body[$langcode][0][value]']", $body, 'The textfield widget is populated.'); } /** * Check that user that does not have access the field format cannot see the * source value when creating a translation. */ function testTextFieldFormatted() { // Make node body multiple. $edit = array('field[cardinality]' => -1); $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings')); $this->drupalGet('node/add/article'); $this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.'); $body = array( $this->randomName(), $this->randomName(), ); // Create an article with the first body input format set to "Full HTML". $title = $this->randomName(); $edit = array( 'title' => $title, 'language' => 'en', ); $this->drupalPost('node/add/article', $edit, t('Save')); // Populate the body field: the first item gets the "Full HTML" input // format, the second one "Filtered HTML". $formats = array('full_html', 'filtered_html'); $langcode = LANGUAGE_NONE; foreach ($body as $delta => $value) { $edit = array( "body[$langcode][$delta][value]" => $value, "body[$langcode][$delta][format]" => array_shift($formats), ); $this->drupalPost('node/1/edit', $edit, t('Save')); $this->assertText($body[$delta], format_string('The body field with delta @delta has been saved.', array('@delta' => $delta))); } // Login as translator. $this->drupalLogin($this->translator); // Translate the article in french. $node = $this->drupalGetNodeByTitle($title); $this->drupalGet("node/$node->nid/translate"); $this->clickLink(t('add translation')); $this->assertNoText($body[0], format_string('The body field with delta @delta is hidden.', array('@delta' => 0))); $this->assertText($body[1], format_string('The body field with delta @delta is shown.', array('@delta' => 1))); } }