You are here

ack_node.test in Access Control Kit 7

Tests for the ACK node module.

File

ack_node/ack_node.test
View source
<?php

/**
 * @file
 * Tests for the ACK node module.
 */

/**
 * Tests the node access functions.
 */
class AckNodeAccessTest extends DrupalWebTestCase {

  /**
   * A user with administrative access.
   *
   * @var object
   */
  protected $adminUser;

  /**
   * An ACK-enabled role that allows editing/deleting the user's own content.
   *
   * @var object
   */
  protected $ackRoleOwn;

  /**
   * An ACK-enabled role that allows editing/deleting any content.
   *
   * @var object
   */
  protected $ackRoleAny;

  /**
   * A user to whom access will be granted during the test.
   *
   * @var object
   */
  protected $ackUser;

  /**
   * A node for testing user access.
   *
   * @var object
   */
  protected $node;

  /**
   * Implements getInfo(), required method for SimpleTest.
   */
  public static function getInfo() {
    return array(
      'name' => 'ACK node access',
      'description' => 'Tests controlling access to nodes.',
      'group' => 'Access control kit',
    );
  }

  /**
   * Overrides DrupalWebTestCase::setUp().
   */
  public function setUp() {
    parent::setUp(array(
      'ack_node',
    ));

    // Create and log in our admin user.
    $this->adminUser = $this
      ->drupalCreateUser(array(
      'administer access schemes',
      'administer access grants',
      'edit any article content',
    ));
    $this
      ->drupalLogin($this->adminUser);

    // Create the test roles.
    $rid = $this
      ->drupalCreateRole(array(
      'ack create article content',
      'ack edit own article content',
      'ack delete own article content',
    ));
    $this->ackRoleOwn = user_role_load($rid);
    $rid = $this
      ->drupalCreateRole(array(
      'ack edit any article content',
      'ack delete any article content',
    ));
    $this->ackRoleAny = user_role_load($rid);

    // Create a user account for use in access grants.
    $this->ackUser = $this
      ->drupalCreateUser(array(
      'access content',
    ));

    // Add the user to the test roles.
    db_insert('users_roles')
      ->fields(array(
      'uid' => $this->ackUser->uid,
      'rid' => $this->ackRoleOwn->rid,
    ))
      ->execute();
    db_insert('users_roles')
      ->fields(array(
      'uid' => $this->ackUser->uid,
      'rid' => $this->ackRoleAny->rid,
    ))
      ->execute();
    $pass_raw = $this->ackUser->pass_raw;
    $this->ackUser = user_load($this->ackUser->uid, TRUE);
    $this->ackUser->pass_raw = $pass_raw;

    // Create the test node.
    $this->node = $this
      ->drupalCreateNode(array(
      'type' => 'article',
    ));
  }

  /**
   * Utility function to prepare a taxonomy-based access test.
   *
   * @param string $scheme_machine_name
   *   The access scheme machine name.
   * @param string $class
   *   The handler class name.
   */
  public function setUpTaxonomy($scheme_machine_name, $class) {

    // Create two tags to use as realms.
    $vocabulary = taxonomy_vocabulary_machine_name_load('tags');
    for ($i = 0; $i < 2; $i++) {
      $term = new stdClass();
      $term->vid = $vocabulary->vid;
      $term->name = $this
        ->randomName();
      taxonomy_term_save($term);
    }

    // Switch the tags field from the tagging widget to checkboxes.
    $instance = field_info_instance('node', 'field_tags', 'article');
    $instance['widget'] = array(
      'type' => 'options_buttons',
      'module' => 'options',
    );
    field_update_instance($instance);

    // Tag the node.
    $edit = array(
      'field_tags[und][1]' => TRUE,
    );
    $this
      ->drupalPost('node/' . $this->node->nid . '/edit', $edit, 'Save');
    $this->node = node_load($this->node->nid, NULL, TRUE);

    // Prepare the access scheme.
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
      'machine_name' => $scheme_machine_name,
      'settings[vocabulary]' => 'tags',
      'roles[' . $this->ackRoleOwn->rid . ']' => TRUE,
      'roles[' . $this->ackRoleAny->rid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/add/taxonomy-term', $edit, 'Save access scheme and continue');
    $edit = array(
      'handlers[node][handler]' => $class,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save access scheme');
    $this
      ->assertText('Updated access scheme ' . $name, 'Access scheme configured.');
  }

  /**
   * Utility function to run taxonomy-related access tests.
   *
   * @param string $scheme_machine_name
   *   The access scheme machine name.
   */
  public function assertTaxonomyAccess($scheme_machine_name) {
    $scheme_field = 'ack_' . $scheme_machine_name;
    $scheme_url = str_replace('_', '-', $scheme_machine_name);

    // Test node access without any grants.
    drupal_static_reset();
    $this
      ->assertFalse(node_access('create', 'article', $this->ackUser), 'User does not have access to create a node.');
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Grant access and retest.
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRoleAny->rid,
      $scheme_field . '[und][1]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/' . $scheme_url, $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('create', 'article', $this->ackUser), 'User does not have access to create a node.');
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Change access and retest.
    $edit = array(
      $scheme_field . '[und][1]' => FALSE,
      $scheme_field . '[und][2]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/grant/1/edit', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('create', 'article', $this->ackUser), 'User does not have access to create a node.');
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Revoke access and retest.
    $edit = array();
    $this
      ->drupalPost('admin/access/grant/1/delete', $edit, 'Delete');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('create', 'article', $this->ackUser), 'User does not have access to create a node.');
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Grant access through the other role and retest.
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRoleOwn->rid,
      $scheme_field . '[und][1]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/' . $scheme_url, $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertTrue(node_access('create', 'article', $this->ackUser), 'User has access to create a node.');
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Change the node's owner and retest.
    $this->node->uid = $this->ackUser->uid;
    node_save($this->node);
    drupal_static_reset();
    $this
      ->assertTrue(node_access('create', 'article', $this->ackUser), 'User has access to create a node.');
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Change access and retest.
    $edit = array(
      $scheme_field . '[und][1]' => FALSE,
      $scheme_field . '[und][2]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/grant/2/edit', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertTrue(node_access('create', 'article', $this->ackUser), 'User has access to create a node.');
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Log in as the ACK user and test realm filtering on the node form.
    $this
      ->drupalLogin($this->ackUser);
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertFieldChecked('edit-field-tags-und-2', 'The only available realm is preselected.');
    $disabled_field = $this
      ->xpath('//input[@id=:id and @disabled="disabled"]', array(
      ':id' => 'edit-field-tags-und-2',
    ));
    $this
      ->assertTrue($disabled_field, 'The realm field is disabled.');
    $this
      ->assertNoFieldById('edit-field-tags-und-1', '', 'The inaccessible realm option was removed.');
    $edit = array(
      'title' => $this
        ->randomName(),
      'body[und][0][value]' => $this
        ->randomName(),
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertText('Article ' . $edit['title'] . ' has been created.', 'User is able to create content in the assigned realm.');
    $this
      ->drupalGet('node/2/edit');
    $this
      ->assertTitle('Edit Article ' . $edit['title'] . ' | Drupal', 'User is able to edit own content in the assigned realm.');
    $this
      ->assertFieldChecked('edit-field-tags-und-2', 'The accessible realm is selected.');
    $disabled_field = $this
      ->xpath('//input[@id=:id and @disabled="disabled"]', array(
      ':id' => 'edit-field-tags-und-2',
    ));
    $this
      ->assertTrue($disabled_field, 'The accessible realm option is disabled.');
    $this
      ->assertNoFieldChecked('edit-field-tags-und-1', 'The inaccessible realm is not selected.');
    $disabled_field = $this
      ->xpath('//input[@id=:id and @disabled="disabled"]', array(
      ':id' => 'edit-field-tags-und-1',
    ));
    $this
      ->assertTrue($disabled_field, 'The inaccessible realm option is disabled.');
    $edit['body[und][0][value]'] = $this
      ->randomName();
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertText('Article ' . $edit['title'] . ' has been updated.', 'User is able to update content in the assigned realm.');

    // Log in as a user with global node access and retest.
    $account = $this
      ->drupalCreateUser(array(
      'access content',
      'create article content',
      'edit own article content',
    ));
    $this
      ->drupalLogin($account);
    $this
      ->drupalGet('node/add/article');
    $disabled_field = $this
      ->xpath('//input[@id=:id and @disabled="disabled"]', array(
      ':id' => 'edit-field-tags-und-2',
    ));
    $this
      ->assertFalse($disabled_field, 'The realm field is not disabled.');
    $this
      ->assertNoFieldChecked('edit-field-tags-und-1');
    $this
      ->assertNoFieldChecked('edit-field-tags-und-2', 'The realm was not preselected.');
    $edit = array(
      'title' => $this
        ->randomName(),
      'body[und][0][value]' => $this
        ->randomName(),
      'field_tags[und][2]' => TRUE,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertText('Article ' . $edit['title'] . ' has been created.', 'User is able to create content.');
    $this
      ->drupalGet('node/3/edit');
    $this
      ->assertTitle('Edit Article ' . $edit['title'] . ' | Drupal', 'User is able to edit own content.');
    $disabled_field = $this
      ->xpath('//input[@id=:id and @disabled="disabled"]', array(
      ':id' => 'edit-field-tags-und-2',
    ));
    $this
      ->assertFalse($disabled_field, 'The realm field is not disabled.');
    $this
      ->assertNoFieldChecked('edit-field-tags-und-1');
    $this
      ->assertFieldChecked('edit-field-tags-und-2', 'The realm is selected.');
    $edit['body[und][0][value]'] = $this
      ->randomName();
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertText('Article ' . $edit['title'] . ' has been updated.', 'User is able to update content.');
  }

  /**
   * Test controlling access by a field value.
   */
  public function testFieldAccess() {
    $this
      ->setUpTaxonomy('test_field_access', 'ACKEntityTaxonomyTermReference');
    $edit = array(
      'handlers[node][ACKEntityTaxonomyTermReference][field_name]' => 'field_tags',
    );
    $this
      ->drupalPost('admin/structure/access/test-field-access', $edit, 'Save access scheme');
    $this
      ->assertText('Updated access scheme', 'Handler settings saved.');
    $this
      ->assertTaxonomyAccess('test_field_access');
  }

  /**
   * Test controlling access with the taxonomy index.
   */
  public function testTaxonomyAccess() {
    $this
      ->setUpTaxonomy('test_taxonomy_access', 'ACKNodeTaxonomyIndex');
    $this
      ->assertTaxonomyAccess('test_taxonomy_access');
  }

  /**
   * Test controlling access by author.
   */
  public function testAuthorAccess() {

    // Prepare the access scheme.
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
      'machine_name' => 'test_author_access',
      'roles[' . $this->ackRoleAny->rid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/add/user', $edit, 'Save access scheme and continue');
    $edit = array(
      'handlers[node][handler]' => 'ACKNodeAuthor',
    );
    $this
      ->drupalPost(NULL, $edit, 'Save access scheme');
    $this
      ->assertText('Updated access scheme ' . $name, 'Access scheme configured.');

    // Test node access without any grants.
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Grant access and retest.
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRoleAny->rid,
      'ack_test_author_access[und][2]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/test-author-access', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Change access and retest.
    $edit = array(
      'ack_test_author_access[und][2]' => FALSE,
      'ack_test_author_access[und][3]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/grant/1/edit', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Change node properties and retest.
    $this->node->uid = 3;
    node_save($this->node);
    drupal_static_reset();
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Revoke access and retest.
    $edit = array();
    $this
      ->drupalPost('admin/access/grant/1/delete', $edit, 'Delete');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');
  }

  /**
   * Test controlling access by stickiness.
   */
  public function testStickyAccess() {

    // Prepare the access scheme.
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
      'machine_name' => 'test_sticky_access',
      'roles[' . $this->ackRoleAny->rid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/add/boolean', $edit, 'Save access scheme and continue');
    $edit = array(
      'handlers[node][handler]' => 'ACKNodeSticky',
    );
    $this
      ->drupalPost(NULL, $edit, 'Save access scheme');
    $this
      ->assertText('Updated access scheme ' . $name, 'Access scheme configured.');

    // Test node access without any grants.
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Grant access and retest.
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRoleAny->rid,
      'ack_test_sticky_access[und][0]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/test-sticky-access', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Change access and retest.
    $edit = array(
      'ack_test_sticky_access[und][0]' => FALSE,
      'ack_test_sticky_access[und][1]' => TRUE,
    );
    $this
      ->drupalPost('admin/access/grant/1/edit', $edit, 'Save');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');

    // Change node properties and retest.
    $this->node->sticky = TRUE;
    node_save($this->node);
    drupal_static_reset();
    $this
      ->assertTrue(node_access('update', $this->node, $this->ackUser), 'User has access to edit the test node.');
    $this
      ->assertTrue(node_access('delete', $this->node, $this->ackUser), 'User has access to delete the test node.');

    // Revoke access and retest.
    $edit = array();
    $this
      ->drupalPost('admin/access/grant/1/delete', $edit, 'Delete');
    drupal_static_reset();
    $this
      ->assertFalse(node_access('update', $this->node, $this->ackUser), 'User does not have access to edit the test node.');
    $this
      ->assertFalse(node_access('delete', $this->node, $this->ackUser), 'User does not have access to delete the test node.');
  }

}

Classes

Namesort descending Description
AckNodeAccessTest Tests the node access functions.