FilterFormatAccessTest.php

Definition of Drupal\filter\Tests\FilterFormatAccessTest.

Namespace

Drupal\filter\Tests

File

drupal/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
View source
<?php

/**
 * @file
 * Definition of Drupal\filter\Tests\FilterFormatAccessTest.
 */
namespace Drupal\filter\Tests;

use Drupal\simpletest\WebTestBase;
class FilterFormatAccessTest extends WebTestBase {
  protected $admin_user;
  protected $filter_admin_user;
  protected $web_user;
  protected $allowed_format;
  protected $disallowed_format;
  public static function getInfo() {
    return array(
      'name' => 'Filter format access',
      'description' => 'Tests access to text formats.',
      'group' => 'Filter',
    );
  }
  function setUp() {
    parent::setUp();
    $this
      ->drupalCreateContentType(array(
      'type' => 'page',
      'name' => 'Basic page',
    ));

    // Create a user who can administer text formats, but does not have
    // specific permission to use any of them.
    $this->filter_admin_user = $this
      ->drupalCreateUser(array(
      'administer filters',
      'create page content',
      'edit any page content',
    ));

    // Create two text formats.
    $this
      ->drupalLogin($this->filter_admin_user);
    $formats = array();
    for ($i = 0; $i < 2; $i++) {
      $edit = array(
        'format' => drupal_strtolower($this
          ->randomName()),
        'name' => $this
          ->randomName(),
      );
      $this
        ->drupalPost('admin/config/content/formats/add', $edit, t('Save configuration'));
      $this
        ->resetFilterCaches();
      $formats[] = filter_format_load($edit['format']);
    }
    list($this->allowed_format, $this->disallowed_format) = $formats;
    $this
      ->drupalLogout();

    // Create a regular user with access to one of the formats.
    $this->web_user = $this
      ->drupalCreateUser(array(
      'create page content',
      'edit any page content',
      filter_permission_name($this->allowed_format),
    ));

    // Create an administrative user who has access to use both formats.
    $this->admin_user = $this
      ->drupalCreateUser(array(
      'administer filters',
      'create page content',
      'edit any page content',
      filter_permission_name($this->allowed_format),
      filter_permission_name($this->disallowed_format),
    ));
  }
  function testFormatPermissions() {

    // Make sure that a regular user only has access to the text format they
    // were granted access to, as well to the fallback format.
    $this
      ->assertTrue(filter_access($this->allowed_format, $this->web_user), 'A regular user has access to a text format they were granted access to.');
    $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.');
    $this
      ->assertTrue(filter_access(filter_format_load(filter_fallback_format()), $this->web_user), 'A regular user has access to the fallback format.');

    // Perform similar checks as above, but now against the entire list of
    // available formats for this user.
    $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.');
    $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.');
    $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.');

    // Make sure that a regular user only has permission to use the format
    // they were granted access to.
    $this
      ->assertTrue(user_access(filter_permission_name($this->allowed_format), $this->web_user), 'A regular user has permission to use the allowed text format.');
    $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.');

    // Make sure that the allowed format appears on the node form and that
    // the disallowed format does not.
    $this
      ->drupalLogin($this->web_user);
    $this
      ->drupalGet('node/add/page');
    $langcode = LANGUAGE_NOT_SPECIFIED;
    $elements = $this
      ->xpath('//select[@name=:name]/option', array(
      ':name' => "body[{$langcode}][0][format]",
      ':option' => $this->allowed_format->format,
    ));
    $options = array();
    foreach ($elements as $element) {
      $options[(string) $element['value']] = $element;
    }
    $this
      ->assertTrue(isset($options[$this->allowed_format->format]), 'The allowed text format appears as an option when adding a new node.');
    $this
      ->assertFalse(isset($options[$this->disallowed_format->format]), 'The disallowed text format does not appear as an option when adding a new node.');
    $this
      ->assertTrue(isset($options[filter_fallback_format()]), 'The fallback format appears as an option when adding a new node.');

    // Check regular user access to the filter tips pages.
    $this
      ->drupalGet('filter/tips/' . $this->allowed_format->format);
    $this
      ->assertResponse(200);
    $this
      ->drupalGet('filter/tips/' . $this->disallowed_format->format);
    $this
      ->assertResponse(403);
    $this
      ->drupalGet('filter/tips/' . filter_fallback_format());
    $this
      ->assertResponse(200);
    $this
      ->drupalGet('filter/tips/invalid-format');
    $this
      ->assertResponse(404);

    // Check admin user access to the filter tips pages.
    $this
      ->drupalLogin($this->admin_user);
    $this
      ->drupalGet('filter/tips/' . $this->allowed_format->format);
    $this
      ->assertResponse(200);
    $this
      ->drupalGet('filter/tips/' . $this->disallowed_format->format);
    $this
      ->assertResponse(200);
    $this
      ->drupalGet('filter/tips/' . filter_fallback_format());
    $this
      ->assertResponse(200);
    $this
      ->drupalGet('filter/tips/invalid-format');
    $this
      ->assertResponse(404);
  }

  /**
   * Tests if text format is available to a role.
   */
  function testFormatRoles() {

    // Get the role ID assigned to the regular user.
    $roles = $this->web_user->roles;
    unset($roles[DRUPAL_AUTHENTICATED_RID]);
    $rid = key($roles);

    // Check that this role appears in the list of roles that have access to an
    // allowed text format, but does not appear in the list of roles that have
    // access to a disallowed text format.
    $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.');
    $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.');

    // Check that the correct text format appears in the list of formats
    // available to that role.
    $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.');
    $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.');

    // Check that the fallback format is always allowed.
    $this
      ->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_roles(), 'All roles have access to the fallback format.');
    $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.');
  }

  /**
   * Tests editing a page using a disallowed text format.
   *
   * Verifies that regular users and administrators are able to edit a page,
   * but not allowed to change the fields which use an inaccessible text
   * format. Also verifies that fields which use a text format that does not
   * exist can be edited by administrators only, but that the administrator is
   * forced to choose a new format before saving the page.
   */
  function testFormatWidgetPermissions() {
    $langcode = LANGUAGE_NOT_SPECIFIED;
    $title_key = "title";
    $body_value_key = "body[{$langcode}][0][value]";
    $body_format_key = "body[{$langcode}][0][format]";

    // Create node to edit.
    $this
      ->drupalLogin($this->admin_user);
    $edit = array();
    $edit['title'] = $this
      ->randomName(8);
    $edit[$body_value_key] = $this
      ->randomName(16);
    $edit[$body_format_key] = $this->disallowed_format->format;
    $this
      ->drupalPost('node/add/page', $edit, t('Save'));
    $node = $this
      ->drupalGetNodeByTitle($edit['title']);

    // Try to edit with a less privileged user.
    $this
      ->drupalLogin($this->web_user);
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->clickLink(t('Edit'));

    // Verify that body field is read-only and contains replacement value.
    $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.');

    // Verify that title can be changed, but preview displays original body.
    $new_edit = array();
    $new_edit['title'] = $this
      ->randomName(8);
    $this
      ->drupalPost(NULL, $new_edit, t('Preview'));
    $this
      ->assertText($edit[$body_value_key], 'Old body found in preview.');

    // Save and verify that only the title was changed.
    $this
      ->drupalPost(NULL, $new_edit, t('Save'));
    $this
      ->assertNoText($edit['title'], 'Old title not found.');
    $this
      ->assertText($new_edit['title'], 'New title found.');
    $this
      ->assertText($edit[$body_value_key], 'Old body found.');

    // Check that even an administrator with "administer filters" permission
    // cannot edit the body field if they do not have specific permission to
    // use its stored format. (This must be disallowed so that the
    // administrator is never forced to switch the text format to something
    // else.)
    $this
      ->drupalLogin($this->filter_admin_user);
    $this
      ->drupalGet('node/' . $node->nid . '/edit');
    $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.');

    // Disable the text format used above.
    filter_format_disable($this->disallowed_format);
    $this
      ->resetFilterCaches();

    // Log back in as the less privileged user and verify that the body field
    // is still disabled, since the less privileged user should not be able to
    // edit content that does not have an assigned format.
    $this
      ->drupalLogin($this->web_user);
    $this
      ->drupalGet('node/' . $node->nid . '/edit');
    $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.');

    // Log back in as the filter administrator and verify that the body field
    // can be edited.
    $this
      ->drupalLogin($this->filter_admin_user);
    $this
      ->drupalGet('node/' . $node->nid . '/edit');
    $this
      ->assertNoFieldByXPath("//textarea[@name='{$body_value_key}' and @disabled='disabled']", NULL, 'Text format access denied message not found.');
    $this
      ->assertFieldByXPath("//select[@name='{$body_format_key}']", NULL, 'Text format selector found.');

    // Verify that trying to save the node without selecting a new text format
    // produces an error message, and does not result in the node being saved.
    $old_title = $new_edit['title'];
    $new_title = $this
      ->randomName(8);
    $edit = array(
      'title' => $new_title,
    );
    $this
      ->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
    $this
      ->assertText(t('!name field is required.', array(
      '!name' => t('Text format'),
    )), 'Error message is displayed.');
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertText($old_title, 'Old title found.');
    $this
      ->assertNoText($new_title, 'New title not found.');

    // Now select a new text format and make sure the node can be saved.
    $edit[$body_format_key] = filter_fallback_format();
    $this
      ->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
    $this
      ->assertUrl('node/' . $node->nid);
    $this
      ->assertText($new_title, 'New title found.');
    $this
      ->assertNoText($old_title, 'Old title not found.');

    // Switch the text format to a new one, then disable that format and all
    // other formats on the site (leaving only the fallback format).
    $this
      ->drupalLogin($this->admin_user);
    $edit = array(
      $body_format_key => $this->allowed_format->format,
    );
    $this
      ->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
    $this
      ->assertUrl('node/' . $node->nid);
    foreach (filter_formats() as $format) {
      if ($format->format != filter_fallback_format()) {
        filter_format_disable($format);
      }
    }

    // Since there is now only one available text format, the widget for
    // selecting a text format would normally not display when the content is
    // edited. However, we need to verify that the filter administrator still
    // is forced to make a conscious choice to reassign the text to a different
    // format.
    $this
      ->drupalLogin($this->filter_admin_user);
    $old_title = $new_title;
    $new_title = $this
      ->randomName(8);
    $edit = array(
      'title' => $new_title,
    );
    $this
      ->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
    $this
      ->assertText(t('!name field is required.', array(
      '!name' => t('Text format'),
    )), 'Error message is displayed.');
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertText($old_title, 'Old title found.');
    $this
      ->assertNoText($new_title, 'New title not found.');
    $edit[$body_format_key] = filter_fallback_format();
    $this
      ->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
    $this
      ->assertUrl('node/' . $node->nid);
    $this
      ->assertText($new_title, 'New title found.');
    $this
      ->assertNoText($old_title, 'Old title not found.');
  }

  /**
   * Rebuild text format and permission caches in the thread running the tests.
   */
  protected function resetFilterCaches() {
    filter_formats_reset();
    $this
      ->checkPermissions(array(), TRUE);
  }

}

Classes