text.test

Tests for text.module.

File

drupal/modules/field/modules/text/text.test
View source
<?php

/**
 * @file
 * Tests for text.module.
 */
class TextFieldTestCase extends DrupalWebTestCase {
  protected $instance;
  protected $admin_user;
  protected $web_user;
  public static function getInfo() {
    return array(
      'name' => '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 = '<em>' . $this
      ->randomName() . '</em>';
    $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. ' . '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. ' . '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 = "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>";

    // The summaries we expect text_summary() to return when $size is the index
    // of each array item.
    // Using no text format:
    $expected = array(
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "<",
      "<p",
      "<p>",
      "<p>\n",
      "<p>\nH",
      "<p>\nHi",
      "<p>\nHi\n",
      "<p>\nHi\n<",
      "<p>\nHi\n</",
      "<p>\nHi\n</p",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
    );

    // And using a text format WITH the line-break and htmlcorrector filters.
    $expected_lb = array(
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "",
      "<p></p>",
      "<p></p>",
      "<p></p>",
      "<p></p>",
      "<p></p>",
      "<p>\nHi</p>",
      "<p>\nHi</p>",
      "<p>\nHi</p>",
      "<p>\nHi</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
      "<p>\nHi\n</p>\n<p>\nfolks\n<br />\n!\n</p>",
    );

    // 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,
    )));
  }

}

Classes