You are here

class AckMenuAccessTest in Access Control Kit 7

Tests the menu access functions.

Hierarchy

Expanded class hierarchy of AckMenuAccessTest

File

ack_menu/ack_menu.test, line 11
Tests for the ACK menu module.

View source
class AckMenuAccessTest extends DrupalWebTestCase {

  /**
   * A user with administrative control over all menus.
   *
   * @var object
   */
  protected $menuAdmin;

  /**
   * A user with administrative control over scheme menus.
   *
   * @var object
   */
  protected $ackAdmin;

  /**
   * An ACK-enabled role that allows managing menu items.
   *
   * @var object
   */
  protected $ackRole;

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

  /**
   * A user with no menu-related access.
   *
   * @var object
   */
  protected $noAccessUser;

  /**
   * An array of menu items for testing user access.
   *
   * @var array
   */
  protected $items;

  /**
   * The machine name of the test access scheme.
   *
   * @var string
   */
  protected $schemeMachineName;

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

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

    // Create and log in our scheme menu admin.
    $this->ackAdmin = $this
      ->drupalCreateUser(array(
      'administer access schemes',
      'administer access grants',
      'administer ack_menu',
      'create article content',
      'edit own article content',
    ));
    $this
      ->drupalLogin($this->ackAdmin);

    // Create the test role.
    $rid = $this
      ->drupalCreateRole(array(
      'ack manage menu links',
      'create article content',
      'edit own article content',
    ));
    $this->ackRole = 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 role.
    db_insert('users_roles')
      ->fields(array(
      'uid' => $this->ackUser->uid,
      'rid' => $this->ackRole->rid,
    ))
      ->execute();
    $pass_raw = $this->ackUser->pass_raw;
    $this->ackUser = user_load($this->ackUser->uid, TRUE);
    $this->ackUser->pass_raw = $pass_raw;

    // Create a user with no menu access.
    $this->noAccessUser = $this
      ->drupalCreateUser(array(
      'access content',
      'create article content',
      'edit own article content',
    ));

    // Create a menu administrator.
    $this->menuAdmin = $this
      ->drupalCreateUser(array(
      'access content',
      'administer menu',
      'administer permissions',
      'create article content',
      'edit own article content',
    ));
  }

  /**
   * Utility function to set up the access scheme.
   */
  public function setUpScheme() {

    // Create a simple user-based scheme.
    $this->schemeMachineName = drupal_strtolower($this
      ->randomName());
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
      'machine_name' => $this->schemeMachineName,
      'roles[' . $this->ackRole->rid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/add/user', $edit, 'Save access scheme and continue');

    // Attach the menu map handler.
    $edit = array(
      'handlers[menu_link][handler]' => 'AckMenuMap',
      'handlers[menu_link][AckMenuMap][menus][navigation]' => TRUE,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save access scheme');
    $this
      ->assertText(t('Updated access scheme @name', array(
      '@name' => $name,
    )), 'Access scheme configured.');
  }

  /**
   * Utility function to set up a menu link access test.
   */
  public function setUpMenu() {
    $this
      ->setUpScheme();

    // Create the test menu items.
    $this->items = array();
    $keys = array(
      'not mapped',
      'mapped top link',
      'mapped child link',
      'not mapped child link',
      'no access child link',
      'no access grandchild link',
      'no access top link',
      'mapped child link with no access parent',
    );
    foreach ($keys as $key) {
      $item = array(
        'link_path' => 'node',
        'link_title' => $this
          ->randomName(),
        'menu_name' => 'navigation',
      );
      switch ($key) {
        case 'mapped child link':
        case 'not mapped child link':
        case 'no access child link':
          $item['plid'] = $this->items['mapped top link']['mlid'];
          break;
        case 'no access grandchild link':
          $item['plid'] = $this->items['no access child link']['mlid'];
          break;
        case 'mapped child link with no access parent':
          $item['plid'] = $this->items['no access top link']['mlid'];
          break;
        default:
          $item['plid'] = NULL;
      }
      $mlid = menu_link_save($item);
      $this->items[$key] = menu_link_load($mlid);
    }
    menu_cache_clear_all();

    // Map the menu items.
    $element = 'AckMenuMap[' . $this->schemeMachineName . ']';
    $edit = array(
      $element => $this->ackUser->uid,
    );
    $this
      ->drupalPost('admin/structure/menu/item/' . $this->items['mapped top link']['mlid'] . '/edit', $edit, 'Save');
    $edit = array(
      $element => $this->ackAdmin->uid,
    );
    $this
      ->drupalPost('admin/structure/menu/item/' . $this->items['mapped child link']['mlid'] . '/edit', $edit, 'Save');
    $this
      ->drupalPost('admin/structure/menu/item/' . $this->items['mapped child link with no access parent']['mlid'] . '/edit', $edit, 'Save');
    $edit = array(
      $element => $this->noAccessUser->uid,
    );
    $this
      ->drupalPost('admin/structure/menu/item/' . $this->items['no access top link']['mlid'] . '/edit', $edit, 'Save');
    $this
      ->drupalPost('admin/structure/menu/item/' . $this->items['no access child link']['mlid'] . '/edit', $edit, 'Save');
  }

  /**
   * Test the menu management UI.
   */
  public function testAckMenuUI() {

    // Check that administrators are notified when no schemes are available.
    $this
      ->clickLink(t('Manage menu links'));
    $this
      ->assertText(t('No access schemes have been configured to manage menu links.'));
    $this
      ->clickLink(t('access scheme administration page'));
    $this
      ->assertLink(t('Add access scheme'));

    // Finish building the test environment.
    $this
      ->setUpMenu();

    // Verify that non-integer schemes cannot use the menu link handler.
    $edit = array(
      'name' => $this
        ->randomName(),
      'machine_name' => drupal_strtolower($this
        ->randomName()),
      'roles[' . $this->ackRole->rid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/add/boolean', $edit, 'Save access scheme and continue');
    $this
      ->assertNoFieldByName('handlers[menu_link][handler]');
    $this
      ->assertText(t('No object access handlers are available to manage Menu link objects in a Boolean scheme.'));
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertFieldByName('AckMenuMap[' . $this->schemeMachineName . ']', '', 'Link can be mapped to an integer scheme.');
    $this
      ->assertNoFieldByName('AckMenuMap[' . $edit['machine_name'] . ']', '', 'Link cannot be mapped to a boolean scheme.');
    $ack_menu_url = 'ack_menu/manage/' . $this->schemeMachineName . '/';
    $ack_link_url = 'admin/structure/menu/item/';

    // Test as the scheme menu admin.
    $this
      ->clickLink(t('Manage menu links'));

    // A scheme menu admin should see all realms.
    $this
      ->assertLinkByHref($ack_menu_url . '1', 0, 'The user 1 realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackAdmin->uid, 0, 'The admin user realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackUser->uid, 0, 'The ACK user realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->noAccessUser->uid, 0, 'The no access user realm is listed.');

    // Test a realm with no mappings.
    $this
      ->drupalGet($ack_menu_url . '1');
    $this
      ->assertTitle(t('Manage @realm menu links', array(
      '@realm' => 'placeholder-for-uid-1',
    )) . ' | Drupal');
    $this
      ->assertText(t('There are no menu links yet for @realm.', array(
      '@realm' => 'placeholder-for-uid-1',
    )));
    $this
      ->assertLink(t('Add a link'));
    $this
      ->assertNoLink(t('Edit the parent link'));
    $edit = array();
    for ($i = 0; $i < 2; $i++) {
      $this
        ->clickLink(t('Add @realm menu link', array(
        '@realm' => 'placeholder-for-uid-1',
      )));
      $selector = $this
        ->xpath('//select[@name=:name and @disabled="disabled"]', array(
        ':name' => 'AckMenuMap[' . $this->schemeMachineName . ']',
      ));
      $this
        ->assertTrue($selector, 'The mapping element is disabled.');
      $this
        ->assertOptionSelected('edit-ackmenumap-' . $this->schemeMachineName, 1, 'The realm mapping is selected.');
      $this
        ->assertOptionSelected('edit-parent', 'navigation:0', 'The parent menu is selected.');
      $this
        ->assertFieldByXPath('//option[@value="navigation:' . $this->items['mapped top link']['mlid'] . '"]', TRUE, 'Links in managed menus from other realms are not filtered.');
      $this
        ->assertNoFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Unmanaged menus are not available as parent options.');
      $edit[$i] = array(
        'link_title' => $this
          ->randomName(),
        'link_path' => 'node',
      );
      $this
        ->drupalPost(NULL, $edit[$i], 'Save');
      $this
        ->assertLink(t('Edit the parent link'), $i);
      if (!$i) {

        // With only one link, the parent link header should not be shown.
        $this
          ->assertNoRaw('<legend><span class="fieldset-legend"><a href="' . url('node') . '" title="">' . $edit[$i]['link_title'] . '</a></span></legend>', 'Parent link header is not displayed when only one parent is present.');
      }
      else {

        // With more than one, we need a header for each.
        $this
          ->assertRaw('<legend><span class="fieldset-legend"><a href="' . url('node') . '" title="">' . $edit[$i]['link_title'] . '</a></span></legend>', 'Parent link headers are displayed when there are two parents available.');
      }
    }

    // Make sure both headers are present.
    $this
      ->assertRaw('<legend><span class="fieldset-legend"><a href="' . url('node') . '" title="">' . $edit[0]['link_title'] . '</a></span></legend>');

    // Check access to menu items.
    $this
      ->clickLink(t('Edit the parent link'));
    $this
      ->assertText(t('Edit menu link'), 'The link can be edited.');
    $selector = $this
      ->xpath('//select[@name=:name and @disabled="disabled"]', array(
      ':name' => 'AckMenuMap[' . $this->schemeMachineName . ']',
    ));
    $this
      ->assertFalse($selector, 'The mapping can be changed.');
    $this
      ->assertOptionSelected('edit-ackmenumap-' . $this->schemeMachineName, 1, 'The realm mapping is selected.');
    $this
      ->drupalPost(NULL, array(), 'Delete');
    $this
      ->assertText(t('Are you sure you want to delete the custom menu link'), 'The link can be deleted.');

    // Check the access callbacks.
    $this
      ->drupalGet($ack_menu_url . 'a');
    $this
      ->assertResponse(403, 'Access is denied to an invalid realm.');
    $this
      ->drupalGet('admin/structure/menu/settings');
    $this
      ->assertResponse(403, 'Access is denied to the menu settings page.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu');
    $this
      ->assertResponse(403, 'Access is denied to an unmanaged menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to an unmanaged menu.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation');
    $this
      ->assertResponse(200, 'Access is granted to a managed menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertResponse(200, 'Access is granted to add a link to a managed menu.');
    $this
      ->drupalGet('admin/structure/menu');
    $this
      ->assertResponse(200, 'Access is granted to the menu admin page.');

    // Check that the menu overview page is properly filtered.
    $this
      ->assertNoLinkByHref('admin/structure/menu/manage/main-menu');
    $this
      ->assertNoLinkByHref('admin/structure/menu/manage/management');
    $this
      ->assertLinkByHref('admin/structure/menu/manage/navigation');
    $this
      ->assertNoLinkByHref('admin/structure/menu/manage/user-menu');
    $this
      ->assertNoLinkByHref('admin/structure/menu/settings');

    // Test as the test user, without an access grant.
    $this
      ->drupalLogin($this->ackUser);
    $this
      ->clickLink(t('Manage menu links'));

    // Without a grant, the menu manager should be empty.
    $this
      ->assertNoLinkByHref($ack_menu_url, 'No realms are listed.');
    $this
      ->assertText(t('You have not been granted access to any menu trees.'));

    // Check the access callbacks.
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid);
    $this
      ->assertResponse(403, 'Access is denied to a menu tree.');
    $this
      ->drupalGet($ack_menu_url . 'a');
    $this
      ->assertResponse(403, 'Access is denied to an invalid realm.');
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid . '/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit an unmapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete an unmapped link.');
    $this
      ->drupalGet('admin/structure/menu');
    $this
      ->assertResponse(403, 'Access is denied to the menu admin page.');
    $this
      ->drupalGet('admin/structure/menu/settings');
    $this
      ->assertResponse(403, 'Access is denied to the menu settings page.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu');
    $this
      ->assertResponse(403, 'Access is denied to an unmanaged menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to an unmanaged menu.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation');
    $this
      ->assertResponse(403, 'Access is denied to a managed menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to a managed menu.');

    // Grant access to the test user.
    $this
      ->drupalLogin($this->ackAdmin);
    $field = 'ack_' . $this->schemeMachineName . '[und]';
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRole->rid,
      $field . '[' . $this->ackUser->uid . ']' => TRUE,
      $field . '[' . $this->ackAdmin->uid . ']' => TRUE,
      $field . '[' . $this->menuAdmin->uid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/' . $this->schemeMachineName, $edit, 'Save');

    // Retest as the test user.
    $this
      ->drupalLogin($this->ackUser);
    $this
      ->clickLink(t('Manage menu links'));

    // With a grant, the menu manager should only list the assigned realms.
    $this
      ->assertNoLinkByHref($ack_menu_url . '1', 'The user 1 realm is not listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackAdmin->uid, 0, 'The admin user realm is listed: ' . $this->ackAdmin->name);
    $this
      ->assertNoLinkByHref($ack_menu_url . $this->menuAdmin->uid, 'The global admin user realm is not listed: ' . $this->menuAdmin->name);
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackUser->uid, 0, 'The ACK user realm is listed: ' . $this->ackUser->name);
    $this
      ->assertNoLinkByHref($ack_menu_url . $this->noAccessUser->uid, 'The no access user realm is not listed: ' . $this->noAccessUser->name);

    // Check the access callbacks.
    $this
      ->drupalGet($ack_menu_url . $this->menuAdmin->uid);
    $this
      ->assertResponse(403, 'Access is denied to a realm menu tree with no mapped links.');
    $this
      ->drupalGet($ack_menu_url . $this->noAccessUser->uid);
    $this
      ->assertResponse(403, 'Access is denied to the no access menu tree.');
    $this
      ->drupalGet($ack_menu_url . 'a');
    $this
      ->assertResponse(403, 'Access is denied to an invalid realm.');
    $this
      ->drupalGet($ack_menu_url . $this->noAccessUser->uid . '/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to the no access realm.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access top link']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit the top link in the no access realm.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access child link']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit a link in the no access realm that is a child of an accessible link.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access grandchild link']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit a link in the no access realm that is a grandchild of an accessible link.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access top link']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete the top link in the no access realm.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access child link']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete a link in the no access realm that is a child of an accessible link.');
    $this
      ->drupalGet($ack_link_url . $this->items['no access grandchild link']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete a link in the no access realm that is a grandchild of an accessible link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit an unmapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete an unmapped link.');
    $this
      ->drupalGet('admin/structure/menu');
    $this
      ->assertResponse(403, 'Access is denied to the menu admin page.');
    $this
      ->drupalGet('admin/structure/menu/settings');
    $this
      ->assertResponse(403, 'Access is denied to the menu settings page.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu');
    $this
      ->assertResponse(403, 'Access is denied to an unmanaged menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to an unmanaged menu.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation');
    $this
      ->assertResponse(403, 'Access is denied to a managed menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to a managed menu.');

    // Put the links we'll be testing into a more easily referenced format.
    // The parent link for the user's realm.
    $parent = new stdClass();
    $parent->mlid = $this->items['mapped top link']['mlid'];
    $parent->plid = $this->items['mapped top link']['plid'];
    $parent->title = $this->items['mapped top link']['title'];
    $parent->field_name = $parent->plid . '[subtree][mlid:' . $parent->mlid . ']';
    $parent->edit = $ack_link_url . $parent->mlid . '/edit';
    $parent->delete = $ack_link_url . $parent->mlid . '/delete';

    // A normal child link of $parent.
    $child = new stdClass();
    $child->mlid = $this->items['not mapped child link']['mlid'];
    $child->title = $this->items['not mapped child link']['title'];
    $child->field_name = $parent->mlid . '[subtree][mlid:' . $child->mlid . ']';
    $child->edit = $ack_link_url . $child->mlid . '/edit';
    $child->delete = $ack_link_url . $child->mlid . '/delete';

    // A child link of $parent explicitly mapped to an accessible foreign realm.
    $foreign_child = new stdClass();
    $foreign_child->mlid = $this->items['mapped child link']['mlid'];
    $foreign_child->title = $this->items['mapped child link']['title'];
    $foreign_child->field_name = $parent->mlid . '[subtree][mlid:' . $foreign_child->mlid . ']';
    $foreign_child->field_id = 'edit-' . $parent->mlid . '-subtree-mlid' . $foreign_child->mlid;
    $foreign_child->edit = $ack_link_url . $foreign_child->mlid . '/edit';
    $foreign_child->delete = $ack_link_url . $foreign_child->mlid . '/delete';

    // A child link of $parent explicitly mapped to an inaccessible realm.
    $no_access_child = new stdClass();
    $no_access_child->mlid = $this->items['no access child link']['mlid'];
    $no_access_child->title = $this->items['no access child link']['title'];
    $no_access_child->field_name = $parent->mlid . '[subtree][mlid:' . $no_access_child->mlid . ']';
    $no_access_child->edit = $ack_link_url . $no_access_child->mlid . '/edit';
    $no_access_child->delete = $ack_link_url . $no_access_child->mlid . '/delete';

    // A child link of $no_access_child.
    $no_access_grandchild = new stdClass();
    $no_access_grandchild->mlid = $this->items['no access grandchild link']['mlid'];
    $no_access_grandchild->title = $this->items['no access grandchild link']['title'];
    $no_access_grandchild->field_name = $no_access_child->mlid . '[subtree][mlid:' . $no_access_grandchild->mlid . ']';

    // Test the subtree for a realm with a top-level mapping.
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid);

    // The parent link.
    $this
      ->assertNoFieldByName($parent->field_name . '[plid]', $parent->plid, 'The parent link does not appear in the subtree: ' . $parent->title);
    $this
      ->assertLinkByHref($parent->edit, 0, 'The parent link shows the edit operation.');
    $this
      ->assertNoLinkByHref($parent->delete, 'The parent link does not show the delete operation.');

    // The normal child link.
    $this
      ->assertFieldByName($child->field_name . '[plid]', $parent->mlid, 'The child link appears in the subtree: ' . $child->title);
    $this
      ->assertLinkByHref($child->edit, 0, 'The child link shows the edit operation.');
    $this
      ->assertLinkByHref($child->delete, 0, 'The child link shows the delete operation.');

    // The accessible foreign child link.
    $this
      ->assertFieldByName($foreign_child->field_name . '[plid]', $parent->mlid, 'The foreign child link appears in the subtree: ' . $foreign_child->title);
    $this
      ->assertLinkByHref($foreign_child->edit, 0, 'The foreign child link shows the edit operation.');
    $this
      ->assertLinkByHref($foreign_child->delete, 0, 'The foreign child link shows the delete operation.');
    $this
      ->assertFieldChecked($foreign_child->field_id . '-hidden', 'The foreign child link is enabled.');

    // The inaccessible foreign child link.
    $this
      ->assertFieldByName($no_access_child->field_name . '[plid]', $parent->mlid, 'The inaccessible child link appears in the subtree: ' . $no_access_child->title);
    $this
      ->assertNoLinkByHref($no_access_child->edit, 'The inaccessible child link does not show the edit operation.');
    $this
      ->assertNoLinkByHref($no_access_child->delete, 'The inaccessible child link does not show the delete operation.');

    // The inaccessible grandchild link.
    $this
      ->assertNoFieldByName($no_access_grandchild->field_name . '[plid]', $parent->mlid, 'The inaccessible grandchild link does not appear in the subtree: ' . $no_access_grandchild->title);
    $this
      ->assertNoLink($no_access_grandchild->title);

    // Test editing a link.
    $edit = array(
      $foreign_child->field_name . '[hidden]' => FALSE,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save configuration');
    $this
      ->assertNoFieldChecked($foreign_child->field_id . '-hidden', 'The foreign child link is disabled: ' . $foreign_child->title);

    // Add a link to the realm.
    $this
      ->clickLink(t('Add @realm menu link', array(
      '@realm' => $this->ackUser->name,
    )));
    $this
      ->assertOptionSelected('edit-parent', 'navigation:' . $parent->mlid, 'The parent link is selected: ' . $parent->title);
    $this
      ->assertFieldByXPath('//option[@value="navigation:' . $child->mlid . '"]', TRUE, 'The child link is an option: ' . $child->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:' . $foreign_child->mlid . '"]', TRUE, 'The foreign child link is not an option: ' . $foreign_child->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:' . $no_access_child->mlid . '"]', TRUE, 'The inaccessible child link is not an option: ' . $no_access_child->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:' . $no_access_grandchild->mlid . '"]', TRUE, 'The inaccessible grandchild link is not an option: ' . $no_access_grandchild->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:0"]', TRUE, 'The parent menu options were filtered.');
    $this
      ->assertNoFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Unmanaged menus are not available as parent options.');
    $edit = array(
      'link_title' => $this
        ->randomName(),
      'link_path' => 'node',
      'parent' => 'navigation:' . $child->mlid,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertText(t('Your configuration has been saved.'));
    $this
      ->assertLink($edit['link_title'], 0, 'The ACK user can create a link.');

    // A few more links for the next set of tests.
    // The parent link of the inaccessible realm.
    $no_access = new stdClass();
    $no_access->mlid = $this->items['no access top link']['mlid'];
    $no_access->title = $this->items['no access top link']['title'];
    $no_access->edit = $ack_link_url . $no_access->mlid . '/edit';
    $no_access->delete = $ack_link_url . $no_access->mlid . '/delete';

    // A link mapped to this realm, but a child of an inaccessible link.
    $child_of_no_access = new stdClass();
    $child_of_no_access->mlid = $this->items['mapped child link with no access parent']['mlid'];
    $child_of_no_access->title = $this->items['mapped child link with no access parent']['title'];
    $child_of_no_access->field_name = $no_access->mlid . '[subtree][mlid:' . $child_of_no_access->mlid . ']';
    $child_of_no_access->edit = $ack_link_url . $child_of_no_access->mlid . '/edit';
    $child_of_no_access->delete = $ack_link_url . $child_of_no_access->mlid . '/delete';

    // Edit the accessible foreign child link.
    $options = array(
      'query' => array(
        'destination' => $ack_menu_url . $this->ackUser->uid,
      ),
    );
    $this
      ->drupalGet($foreign_child->edit, $options);
    $this
      ->assertOptionSelected('edit-parent', 'navigation:' . $parent->mlid, 'The parent link is selected: ' . $parent->title);
    $this
      ->assertNoOptionSelected('edit-parent', 'navigation:' . $child_of_no_access->mlid, 'The other potential parent option is available, but not selected: ' . $child_of_no_access->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:' . $no_access->mlid . '"]', TRUE, 'The "no access" realm parent link is not available as a parent option: ' . $no_access->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:0"]', TRUE, 'The parent menu options were filtered.');
    $this
      ->assertNoFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Unmanaged menus are not available as parent options.');
    $selector = $this
      ->xpath('//select[@name=:name and @disabled="disabled"]', array(
      ':name' => 'weight',
    ));
    $this
      ->assertFalse($selector, 'The weight element is not disabled.');
    $this
      ->drupalPost(NULL, array(
      'enabled' => TRUE,
    ), 'Save');
    $this
      ->assertText(t('Your configuration has been saved.'));
    $this
      ->assertFieldChecked($foreign_child->field_id . '-hidden', 'The ACK user can edit a link.');

    // Test the subtrees for a realm with child-level mappings.
    $this
      ->drupalGet($ack_menu_url . $this->ackAdmin->uid);
    $this
      ->assertNoLinkByHref($no_access->edit, 'The "no access" realm parent link is not listed.');
    $this
      ->assertNoFieldByName($foreign_child->field_name . '[plid]', $parent->mlid, 'The link with the accessible parent does not appear in the subtree: ' . $foreign_child->title);
    $this
      ->assertLink($foreign_child->title);
    $this
      ->assertLinkByHref($foreign_child->edit, 0, 'The link with the accessible parent shows the edit operation.');
    $this
      ->assertNoLinkByHref($foreign_child->delete, 'The link with the accessible parent does not show the delete operation.');
    $this
      ->assertNoFieldByName($child_of_no_access->field_name . '[plid]', $no_access->mlid, 'The link with the inaccessible parent does not appear in a subtree for its parent: ' . $child_of_no_access->title);
    $this
      ->assertNoFieldByName($foreign_child->mlid . '[subtree][mlid:' . $child_of_no_access->mlid . ']' . '[plid]', $no_access->mlid, 'The link with the inaccessible parent does not appear in a subtree for the link with the accessible parent: ' . $child_of_no_access->title);
    $this
      ->assertLink($child_of_no_access->title);
    $this
      ->assertLinkByHref($child_of_no_access->edit, 0, 'The link with the inaccessible parent shows the edit operation.');
    $this
      ->assertNoLinkByHref($child_of_no_access->delete, 'The link with the inaccessible parent does not show the delete operation.');

    // Delete the link with the accessible parent.
    $options = array(
      'query' => array(
        'destination' => $ack_menu_url . $this->ackAdmin->uid,
      ),
    );
    $this
      ->drupalPost($foreign_child->delete, array(), 'Confirm', $options);
    $this
      ->assertText(t('The menu link @title has been deleted.', array(
      '@title' => $foreign_child->title,
    )));
    $this
      ->assertNoLinkByHref($foreign_child->edit, 'The ACK user can delete a link.');
    $this
      ->assertLinkByHref($child_of_no_access->edit, 0, 'The link with the inaccessible parent is still available.');

    // Test editing an item with an inaccessible parent.
    $this
      ->clickLink(t('Edit the parent link'));
    $this
      ->assertFieldByName('link_title', $child_of_no_access->title);
    $this
      ->assertOptionSelected('edit-parent', 'navigation:' . $no_access->mlid, 'The parent is selected: ' . $no_access->title);
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:' . $parent->mlid . '"]', TRUE, 'The parent link options were filtered.');
    $selector = $this
      ->xpath('//select[@name=:name and @disabled="disabled"]', array(
      ':name' => 'weight',
    ));
    $this
      ->assertTrue($selector, 'The weight element is disabled.');

    // Test as a user with no menu-related access.
    $this
      ->drupalLogin($this->noAccessUser);
    $this
      ->assertNoLink(t('Manage menu links'));

    // Check the access callbacks.
    $this
      ->drupalGet('ack_menu');
    $this
      ->assertResponse(403, 'Access is denied to the menu manager.');
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid);
    $this
      ->assertResponse(403, 'Access is denied to a menu tree.');
    $this
      ->drupalGet($ack_menu_url . 'a');
    $this
      ->assertResponse(403, 'Access is denied to an invalid realm.');
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid . '/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/edit');
    $this
      ->assertResponse(403, 'Access is denied to edit an unmapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/delete');
    $this
      ->assertResponse(403, 'Access is denied to delete an unmapped link.');
    $this
      ->drupalGet('admin/structure/menu');
    $this
      ->assertResponse(403, 'Access is denied to the menu admin page.');
    $this
      ->drupalGet('admin/structure/menu/settings');
    $this
      ->assertResponse(403, 'Access is denied to the menu settings page.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu');
    $this
      ->assertResponse(403, 'Access is denied to an unmanaged menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to an unmanaged menu.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation');
    $this
      ->assertResponse(403, 'Access is denied to a managed menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertResponse(403, 'Access is denied to add a link to a managed menu.');

    // Test as the menu administrator.
    $this
      ->drupalLogin($this->menuAdmin);
    $this
      ->clickLink(t('Manage menu links'));

    // A menu admin should see all realms.
    $this
      ->assertLinkByHref($ack_menu_url . '1', 0, 'The user 1 realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackAdmin->uid, 0, 'The admin user realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->ackUser->uid, 0, 'The ACK user realm is listed.');
    $this
      ->assertLinkByHref($ack_menu_url . $this->noAccessUser->uid, 0, 'The no access user realm is listed.');

    // Check the access callbacks.
    $this
      ->assertResponse(200, 'Access is granted to the menu manager.');
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid);
    $this
      ->assertResponse(200, 'Access is granted to a menu tree.');
    $this
      ->drupalGet($ack_menu_url . 'a');
    $this
      ->assertResponse(403, 'Access is denied to an invalid realm.');
    $this
      ->drupalGet($ack_menu_url . $this->ackUser->uid . '/add');
    $this
      ->assertResponse(200, 'Access is granted to add a link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/edit');
    $this
      ->assertResponse(200, 'Access is granted to edit a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['mapped top link']['mlid'] . '/delete');
    $this
      ->assertResponse(200, 'Access is granted to delete a mapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/edit');
    $this
      ->assertResponse(200, 'Access is granted to edit an unmapped link.');
    $this
      ->drupalGet($ack_link_url . $this->items['not mapped']['mlid'] . '/delete');
    $this
      ->assertResponse(200, 'Access is granted to delete an unmapped link.');
    $this
      ->drupalGet('admin/structure/menu/settings');
    $this
      ->assertResponse(200, 'Access is granted to the menu settings page.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu');
    $this
      ->assertResponse(200, 'Access is granted to an unmanaged menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/main-menu/add');
    $this
      ->assertResponse(200, 'Access is granted to add a link to an unmanaged menu.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation');
    $this
      ->assertResponse(200, 'Access is granted to a managed menu list.');
    $this
      ->drupalGet('admin/structure/menu/manage/navigation/add');
    $this
      ->assertResponse(200, 'Access is granted to add a link to a managed menu.');
    $this
      ->drupalGet('admin/structure/menu');
    $this
      ->assertResponse(200, 'Access is granted to the menu admin page.');

    // Check that the menu overview page is not filtered.
    $this
      ->assertLinkByHref('admin/structure/menu/manage/main-menu');
    $this
      ->assertLinkByHref('admin/structure/menu/manage/management');
    $this
      ->assertLinkByHref('admin/structure/menu/manage/navigation');
    $this
      ->assertLinkByHref('admin/structure/menu/manage/user-menu');
    $this
      ->assertLinkByHref('admin/structure/menu/settings');

    // Check the permission descriptions.
    $this
      ->drupalGet('admin/people/permissions');
    $this
      ->assertText(t('Manage the links in the following access scheme-controlled menus: @menus.', array(
      '@menus' => 'Navigation',
    )), 'Permissions page lists manageable menus.');
    $scheme = access_scheme_machine_name_load($this->schemeMachineName);
    $this
      ->assertText(t('This permission only applies to the following access schemes: @schemes.', array(
      '@schemes' => $scheme->name,
    )), 'Permissions page lists applicable schemes.');
  }

  /**
   * Test controlling access to the node menu options.
   */
  public function testNodeMenuUI() {
    $this
      ->setUpMenu();

    // Test as the scheme menu admin, but with no usable menus on the node.
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertNoText(t('Provide a menu link'));
    variable_set('menu_options_article', array(
      'main-menu',
      'management',
    ));
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertNoText(t('Provide a menu link'));

    // Add the node's menu to the scheme and retest.
    $edit = array(
      'handlers[menu_link][AckMenuMap][menus][main-menu]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/access/' . $this->schemeMachineName, $edit, 'Save access scheme');
    $this
      ->assertText(t('Updated access scheme'), 'Access scheme configured.');
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertText(t('Provide a menu link'));
    $this
      ->assertNoFieldByXPath('//option[@value="management:0"]', TRUE, 'Removed parent option: management');
    $edit = array(
      'title' => $this
        ->randomName(),
      'menu[enabled]' => TRUE,
      'menu[link_title]' => $this
        ->randomName(),
      'menu[parent]' => 'main-menu:0',
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertLink($edit['menu[link_title]'], 0, 'The scheme menu admin can create a link from the node form.');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertFieldChecked('edit-menu-enabled');
    $this
      ->assertOptionSelected('edit-menu-parent', 'main-menu:0');

    // Test as the test user, without an access grant.
    $this
      ->drupalLogin($this->ackUser);
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertNoText(t('Provide a menu link'));
    $this
      ->drupalPost(NULL, array(
      'title' => $this
        ->randomName(),
    ), 'Save');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertNoText(t('Provide a menu link'), 'The ACK user cannot create a link from the node form without a grant.');

    // Grant access to the test user.
    $this
      ->drupalLogin($this->ackAdmin);
    $field = 'ack_' . $this->schemeMachineName . '[und]';
    $edit = array(
      'user' => $this->ackUser->name,
      'role' => $this->ackRole->rid,
      $field . '[' . $this->ackUser->uid . ']' => TRUE,
      $field . '[' . $this->ackAdmin->uid . ']' => TRUE,
    );
    $this
      ->drupalPost('admin/access/add/' . $this->schemeMachineName, $edit, 'Save');

    // Retest as the test user, but with no usable menus on the node.
    $this
      ->drupalLogin($this->ackUser);
    variable_set('menu_options_article', array(
      'main-menu',
    ));
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertNoText(t('Provide a menu link'));
    $this
      ->drupalPost(NULL, array(
      'title' => $this
        ->randomName(),
    ), 'Save');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertNoText(t('Provide a menu link'), 'The ACK user cannot create a link from the node form without a usable menu.');

    // Retest with a usable menu.
    variable_set('menu_options_article', array(
      'main-menu',
      'navigation',
    ));
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertText(t('Provide a menu link'));

    // Check parent option filtering before save.
    $options = array(
      'mapped top link' => TRUE,
      'mapped child link' => TRUE,
      'no access child link' => FALSE,
      'no access grandchild link' => FALSE,
      'mapped child link with no access parent' => TRUE,
      'not mapped' => FALSE,
      'no access top link' => FALSE,
    );
    foreach ($options as $key => $allowed) {
      $xpath = '//option[@value="navigation:' . $this->items[$key]['mlid'] . '"]';
      if ($allowed) {
        $this
          ->assertFieldByXPath($xpath, TRUE, 'Allowed parent option: ' . $key);
      }
      else {
        $this
          ->assertNoFieldByXPath($xpath, TRUE, 'Removed parent option: ' . $key);
      }
    }
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:0"]', TRUE, 'Removed parent option: navigation');
    $this
      ->assertNoFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Removed parent option: main menu');

    // Check parent option filtering after save.
    $parent = 'navigation:' . $this->items['mapped top link']['mlid'];
    $edit = array(
      'title' => $this
        ->randomName(),
      'menu[enabled]' => TRUE,
      'menu[link_title]' => $this
        ->randomName(),
      'menu[parent]' => $parent,
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertLink($edit['menu[link_title]'], 0, 'The ACK user can create a link from the node form.');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertFieldChecked('edit-menu-enabled');
    $this
      ->assertOptionSelected('edit-menu-parent', $parent);

    // Links from realms other than the one that currently owns this link should
    // be excluded from the parent options.
    $options['mapped child link'] = FALSE;
    $options['mapped child link with no access parent'] = FALSE;
    foreach ($options as $key => $allowed) {
      $xpath = '//option[@value="navigation:' . $this->items[$key]['mlid'] . '"]';
      if ($allowed) {
        $this
          ->assertFieldByXPath($xpath, TRUE, 'Allowed parent option: ' . $key);
      }
      else {
        $this
          ->assertNoFieldByXPath($xpath, TRUE, 'Removed parent option: ' . $key);
      }
    }
    $this
      ->assertNoFieldByXPath('//option[@value="navigation:0"]', TRUE, 'Removed parent option: navigation');
    $this
      ->assertNoFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Removed parent option: main menu');

    // Test a node with an inaccessible link.
    $this
      ->drupalLogin($this->ackAdmin);
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'article',
      'uid' => $this->ackUser->uid,
    ));
    $edit = array(
      'link_title' => $this
        ->randomName(),
      'link_path' => 'node/' . $node->nid,
    );
    $this
      ->drupalPost('ack_menu/manage/' . $this->schemeMachineName . '/' . $this->noAccessUser->uid . '/add', $edit, 'Save');
    $this
      ->drupalLogin($this->ackUser);
    $this
      ->drupalGet('node/' . $node->nid . '/edit');
    $this
      ->assertText(t('Edit Article @title', array(
      '@title' => $node->title,
    )));
    $this
      ->assertNoText(t('Provide a menu link'), 'The ACK user cannot edit a link owned by a foreign realm.');

    // Test as a user with no menu-related access.
    $this
      ->drupalLogin($this->noAccessUser);
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertNoText(t('Provide a menu link'));
    $this
      ->drupalPost(NULL, array(
      'title' => $this
        ->randomName(),
    ), 'Save');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertNoText(t('Provide a menu link'), 'A user with no menu-related access cannot create a link from the node form.');

    // Test as the menu administrator.
    $this
      ->drupalLogin($this->menuAdmin);
    $this
      ->drupalGet('node/add/article');
    $this
      ->assertText(t('Provide a menu link'));
    $this
      ->assertFieldByXPath('//option[@value="navigation:0"]', TRUE, 'Allowed parent option: navigation');
    $this
      ->assertFieldByXPath('//option[@value="main-menu:0"]', TRUE, 'Allowed parent option: main menu');
    $edit = array(
      'title' => $this
        ->randomName(),
      'menu[enabled]' => TRUE,
      'menu[link_title]' => $this
        ->randomName(),
      'menu[parent]' => 'main-menu:0',
    );
    $this
      ->drupalPost(NULL, $edit, 'Save');
    $this
      ->assertLink($edit['menu[link_title]'], 0, 'The menu admin can create a link from the node form.');
    $this
      ->clickLink(t('Edit'));
    $this
      ->assertFieldChecked('edit-menu-enabled');
    $this
      ->assertOptionSelected('edit-menu-parent', 'main-menu:0');
  }

  /**
   * Test that the module responds appropriately to events that affect the map.
   */
  public function testEventHooks() {
    $this
      ->setUpScheme();
    $scheme = access_scheme_machine_name_load($this->schemeMachineName);

    // Create two mapped links.
    for ($i = 0; $i < 2; $i++) {
      $edit = array(
        'link_title' => $this
          ->randomName(),
        'link_path' => 'node',
      );
      $this
        ->drupalPost('ack_menu/manage/' . $scheme->machine_name . '/' . $this->ackUser->uid . '/add', $edit, 'Save');
    }

    // Confirm that mappings are deleted when links are deleted.
    $links = ack_menu_realm_links($scheme, $this->ackUser->uid, NULL, TRUE);
    $this
      ->assertEqual(count($links), 2, 'Two mappings found.');
    $link = reset($links);
    menu_link_delete($link['mlid']);
    $this
      ->assertFalse(menu_link_load($link['mlid']), 'One link deleted.');
    $links = ack_menu_realm_links($scheme, $this->ackUser->uid, NULL, TRUE);
    $this
      ->assertEqual(count($links), 1, 'One mapping remains.');

    // Create a second scheme with a mapped link.
    $this
      ->setUpScheme();
    $new_scheme = access_scheme_machine_name_load($this->schemeMachineName);
    $edit = array(
      'link_title' => $this
        ->randomName(),
      'link_path' => 'node',
    );
    $this
      ->drupalPost('ack_menu/manage/' . $new_scheme->machine_name . '/' . $this->ackUser->uid . '/add', $edit, 'Save');

    // Confirm that mappings are deleted when schemes are deleted.
    $new_links = ack_menu_realm_links($new_scheme, $this->ackUser->uid, NULL, TRUE);
    $this
      ->assertEqual(count($links) + count($new_links), 2, 'Two mappings found.');
    access_scheme_delete($new_scheme->sid);
    $this
      ->assertFalse(access_scheme_load($new_scheme->sid), 'One scheme deleted.');
    $new_links = ack_menu_realm_links($new_scheme, $this->ackUser->uid, NULL, TRUE);
    $this
      ->assertEqual(count($links) + count($new_links), 1, 'One mapping remains.');
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AckMenuAccessTest::$ackAdmin protected property A user with administrative control over scheme menus.
AckMenuAccessTest::$ackRole protected property An ACK-enabled role that allows managing menu items.
AckMenuAccessTest::$ackUser protected property A user to whom access will be granted during the test.
AckMenuAccessTest::$items protected property An array of menu items for testing user access.
AckMenuAccessTest::$menuAdmin protected property A user with administrative control over all menus.
AckMenuAccessTest::$noAccessUser protected property A user with no menu-related access.
AckMenuAccessTest::$schemeMachineName protected property The machine name of the test access scheme.
AckMenuAccessTest::getInfo public static function Implements getInfo(), required method for SimpleTest.
AckMenuAccessTest::setUp public function Overrides DrupalWebTestCase::setUp(). Overrides DrupalWebTestCase::setUp
AckMenuAccessTest::setUpMenu public function Utility function to set up a menu link access test.
AckMenuAccessTest::setUpScheme public function Utility function to set up the access scheme.
AckMenuAccessTest::testAckMenuUI public function Test the menu management UI.
AckMenuAccessTest::testEventHooks public function Test that the module responds appropriately to events that affect the map.
AckMenuAccessTest::testNodeMenuUI public function Test controlling access to the node menu options.
DrupalTestCase::$assertions protected property Assertions thrown in that test case.
DrupalTestCase::$databasePrefix protected property The database prefix of this test run.
DrupalTestCase::$originalFileDirectory protected property The original file directory, before it was changed for testing purposes.
DrupalTestCase::$results public property Current results of this test case.
DrupalTestCase::$setup protected property Flag to indicate whether the test has been set up.
DrupalTestCase::$setupDatabasePrefix protected property
DrupalTestCase::$setupEnvironment protected property
DrupalTestCase::$skipClasses protected property This class is skipped when looking for the source of an assertion.
DrupalTestCase::$testId protected property The test run ID.
DrupalTestCase::$timeLimit protected property Time limit for the test.
DrupalTestCase::$useSetupInstallationCache public property Whether to cache the installation part of the setUp() method.
DrupalTestCase::$useSetupModulesCache public property Whether to cache the modules installation part of the setUp() method.
DrupalTestCase::$verboseDirectoryUrl protected property URL to the verbose output file directory.
DrupalTestCase::assert protected function Internal helper: stores the assert.
DrupalTestCase::assertEqual protected function Check to see if two values are equal.
DrupalTestCase::assertFalse protected function Check to see if a value is false (an empty string, 0, NULL, or FALSE).
DrupalTestCase::assertIdentical protected function Check to see if two values are identical.
DrupalTestCase::assertNotEqual protected function Check to see if two values are not equal.
DrupalTestCase::assertNotIdentical protected function Check to see if two values are not identical.
DrupalTestCase::assertNotNull protected function Check to see if a value is not NULL.
DrupalTestCase::assertNull protected function Check to see if a value is NULL.
DrupalTestCase::assertTrue protected function Check to see if a value is not false (not an empty string, 0, NULL, or FALSE).
DrupalTestCase::deleteAssert public static function Delete an assertion record by message ID.
DrupalTestCase::error protected function Fire an error assertion. 1
DrupalTestCase::errorHandler public function Handle errors during test runs. 1
DrupalTestCase::exceptionHandler protected function Handle exceptions.
DrupalTestCase::fail protected function Fire an assertion that is always negative.
DrupalTestCase::generatePermutations public static function Converts a list of possible parameters into a stack of permutations.
DrupalTestCase::getAssertionCall protected function Cycles through backtrace until the first non-assertion method is found.
DrupalTestCase::getDatabaseConnection public static function Returns the database connection to the site running Simpletest.
DrupalTestCase::insertAssert public static function Store an assertion from outside the testing context.
DrupalTestCase::pass protected function Fire an assertion that is always positive.
DrupalTestCase::randomName public static function Generates a random string containing letters and numbers.
DrupalTestCase::randomString public static function Generates a random string of ASCII characters of codes 32 to 126.
DrupalTestCase::run public function Run all tests in this class.
DrupalTestCase::verbose protected function Logs a verbose message in a text file.
DrupalWebTestCase::$additionalCurlOptions protected property Additional cURL options.
DrupalWebTestCase::$content protected property The content of the page currently loaded in the internal browser.
DrupalWebTestCase::$cookieFile protected property The current cookie file used by cURL.
DrupalWebTestCase::$cookies protected property The cookies of the page currently loaded in the internal browser.
DrupalWebTestCase::$curlHandle protected property The handle of the current cURL connection.
DrupalWebTestCase::$drupalSettings protected property The value of the Drupal.settings JavaScript variable for the page currently loaded in the internal browser.
DrupalWebTestCase::$elements protected property The parsed version of the page.
DrupalWebTestCase::$generatedTestFiles protected property Whether the files were copied to the test files directory.
DrupalWebTestCase::$headers protected property The headers of the page currently loaded in the internal browser.
DrupalWebTestCase::$httpauth_credentials protected property HTTP authentication credentials (<username>:<password>).
DrupalWebTestCase::$httpauth_method protected property HTTP authentication method
DrupalWebTestCase::$loggedInUser protected property The current user logged in using the internal browser.
DrupalWebTestCase::$originalShutdownCallbacks protected property The original shutdown handlers array, before it was cleaned for testing purposes.
DrupalWebTestCase::$originalUser protected property The original user, before it was changed to a clean uid = 1 for testing purposes.
DrupalWebTestCase::$plainTextContent protected property The content of the page currently loaded in the internal browser (plain text version).
DrupalWebTestCase::$profile protected property The profile to install as a basis for testing. 20
DrupalWebTestCase::$redirect_count protected property The number of redirects followed during the handling of a request.
DrupalWebTestCase::$session_id protected property The current session ID, if available.
DrupalWebTestCase::$session_name protected property The current session name, if available.
DrupalWebTestCase::$url protected property The URL currently loaded in the internal browser.
DrupalWebTestCase::assertField protected function Asserts that a field exists with the given name or ID.
DrupalWebTestCase::assertFieldById protected function Asserts that a field exists in the current page with the given ID and value.
DrupalWebTestCase::assertFieldByName protected function Asserts that a field exists in the current page with the given name and value.
DrupalWebTestCase::assertFieldByXPath protected function Asserts that a field exists in the current page by the given XPath.
DrupalWebTestCase::assertFieldChecked protected function Asserts that a checkbox field in the current page is checked.
DrupalWebTestCase::assertLink protected function Pass if a link with the specified label is found, and optional with the specified index.
DrupalWebTestCase::assertLinkByHref protected function Pass if a link containing a given href (part) is found.
DrupalWebTestCase::assertMail protected function Asserts that the most recently sent e-mail message has the given value.
DrupalWebTestCase::assertMailPattern protected function Asserts that the most recently sent e-mail message has the pattern in it.
DrupalWebTestCase::assertMailString protected function Asserts that the most recently sent e-mail message has the string in it.
DrupalWebTestCase::assertNoDuplicateIds protected function Asserts that each HTML ID is used for just a single element.
DrupalWebTestCase::assertNoField protected function Asserts that a field does not exist with the given name or ID.
DrupalWebTestCase::assertNoFieldById protected function Asserts that a field does not exist with the given ID and value.
DrupalWebTestCase::assertNoFieldByName protected function Asserts that a field does not exist with the given name and value.
DrupalWebTestCase::assertNoFieldByXPath protected function Asserts that a field doesn't exist or its value doesn't match, by XPath.
DrupalWebTestCase::assertNoFieldChecked protected function Asserts that a checkbox field in the current page is not checked.
DrupalWebTestCase::assertNoLink protected function Pass if a link with the specified label is not found.
DrupalWebTestCase::assertNoLinkByHref protected function Pass if a link containing a given href (part) is not found.
DrupalWebTestCase::assertNoOptionSelected protected function Asserts that a select option in the current page is not checked.
DrupalWebTestCase::assertNoPattern protected function Will trigger a pass if the perl regex pattern is not present in raw content.
DrupalWebTestCase::assertNoRaw protected function Pass if the raw text is NOT found on the loaded page, fail otherwise. Raw text refers to the raw HTML that the page generated.
DrupalWebTestCase::assertNoResponse protected function Asserts the page did not return the specified response code.
DrupalWebTestCase::assertNoText protected function Pass if the text is NOT found on the text version of the page. The text version is the equivalent of what a user would see when viewing through a web browser. In other words the HTML has been filtered out of the contents.
DrupalWebTestCase::assertNoTitle protected function Pass if the page title is not the given string.
DrupalWebTestCase::assertNoUniqueText protected function Pass if the text is found MORE THAN ONCE on the text version of the page.
DrupalWebTestCase::assertOptionSelected protected function Asserts that a select option in the current page is checked.
DrupalWebTestCase::assertPattern protected function Will trigger a pass if the Perl regex pattern is found in the raw content.
DrupalWebTestCase::assertRaw protected function Pass if the raw text IS found on the loaded page, fail otherwise. Raw text refers to the raw HTML that the page generated.
DrupalWebTestCase::assertResponse protected function Asserts the page responds with the specified response code.
DrupalWebTestCase::assertText protected function Pass if the text IS found on the text version of the page. The text version is the equivalent of what a user would see when viewing through a web browser. In other words the HTML has been filtered out of the contents.
DrupalWebTestCase::assertTextHelper protected function Helper for assertText and assertNoText.
DrupalWebTestCase::assertThemeOutput protected function Asserts themed output.
DrupalWebTestCase::assertTitle protected function Pass if the page title is the given string.
DrupalWebTestCase::assertUniqueText protected function Pass if the text is found ONLY ONCE on the text version of the page.
DrupalWebTestCase::assertUniqueTextHelper protected function Helper for assertUniqueText and assertNoUniqueText.
DrupalWebTestCase::assertUrl protected function Pass if the internal browser's URL matches the given path.
DrupalWebTestCase::buildXPathQuery protected function Builds an XPath query.
DrupalWebTestCase::changeDatabasePrefix protected function Changes the database connection to the prefixed one.
DrupalWebTestCase::checkForMetaRefresh protected function Check for meta refresh tag and if found call drupalGet() recursively. This function looks for the http-equiv attribute to be set to "Refresh" and is case-sensitive.
DrupalWebTestCase::checkPermissions protected function Check to make sure that the array of permissions are valid.
DrupalWebTestCase::clickLink protected function Follows a link by name.
DrupalWebTestCase::constructFieldXpath protected function Helper function: construct an XPath for the given set of attributes and value.
DrupalWebTestCase::copySetupCache protected function Copy the setup cache from/to another table and files directory.
DrupalWebTestCase::cronRun protected function Runs cron in the Drupal installed by Simpletest.
DrupalWebTestCase::curlClose protected function Close the cURL handler and unset the handler.
DrupalWebTestCase::curlExec protected function Initializes and executes a cURL request.
DrupalWebTestCase::curlHeaderCallback protected function Reads headers and registers errors received from the tested site.
DrupalWebTestCase::curlInitialize protected function Initializes the cURL connection.
DrupalWebTestCase::drupalCompareFiles protected function Compare two files based on size and file name.
DrupalWebTestCase::drupalCreateContentType protected function Creates a custom content type based on default settings.
DrupalWebTestCase::drupalCreateNode protected function Creates a node based on default settings.
DrupalWebTestCase::drupalCreateRole protected function Creates a role with specified permissions.
DrupalWebTestCase::drupalCreateUser protected function Create a user with a given set of permissions.
DrupalWebTestCase::drupalGet protected function Retrieves a Drupal path or an absolute path.
DrupalWebTestCase::drupalGetAJAX protected function Retrieve a Drupal path or an absolute path and JSON decode the result.
DrupalWebTestCase::drupalGetContent protected function Gets the current raw HTML of requested page.
DrupalWebTestCase::drupalGetHeader protected function Gets the value of an HTTP response header. If multiple requests were required to retrieve the page, only the headers from the last request will be checked by default. However, if TRUE is passed as the second argument, all requests will be processed…
DrupalWebTestCase::drupalGetHeaders protected function Gets the HTTP response headers of the requested page. Normally we are only interested in the headers returned by the last request. However, if a page is redirected or HTTP authentication is in use, multiple requests will be required to retrieve the…
DrupalWebTestCase::drupalGetMails protected function Gets an array containing all e-mails sent during this test case.
DrupalWebTestCase::drupalGetNodeByTitle function Get a node from the database based on its title.
DrupalWebTestCase::drupalGetSettings protected function Gets the value of the Drupal.settings JavaScript variable for the currently loaded page.
DrupalWebTestCase::drupalGetTestFiles protected function Get a list files that can be used in tests.
DrupalWebTestCase::drupalGetToken protected function Generate a token for the currently logged in user.
DrupalWebTestCase::drupalHead protected function Retrieves only the headers for a Drupal path or an absolute path.
DrupalWebTestCase::drupalLogin protected function Log in a user with the internal browser.
DrupalWebTestCase::drupalLogout protected function
DrupalWebTestCase::drupalPost protected function Execute a POST request on a Drupal page. It will be done as usual POST request with SimpleBrowser.
DrupalWebTestCase::drupalPostAJAX protected function Execute an Ajax submission.
DrupalWebTestCase::drupalSetContent protected function Sets the raw HTML content. This can be useful when a page has been fetched outside of the internal browser and assertions need to be made on the returned page.
DrupalWebTestCase::drupalSetSettings protected function Sets the value of the Drupal.settings JavaScript variable for the currently loaded page.
DrupalWebTestCase::getAbsoluteUrl protected function Takes a path and returns an absolute path.
DrupalWebTestCase::getAllOptions protected function Get all option elements, including nested options, in a select.
DrupalWebTestCase::getSelectedItem protected function Get the selected value from a select field.
DrupalWebTestCase::getSetupCacheKey protected function Returns the cache key used for the setup caching.
DrupalWebTestCase::getUrl protected function Get the current URL from the cURL handler.
DrupalWebTestCase::handleForm protected function Handle form input related to drupalPost(). Ensure that the specified fields exist and attempt to create POST data in the correct manner for the particular field type.
DrupalWebTestCase::loadSetupCache protected function Copies the cached tables and files for a cached installation setup.
DrupalWebTestCase::parse protected function Parse content returned from curlExec using DOM and SimpleXML.
DrupalWebTestCase::preloadRegistry protected function Preload the registry from the testing site.
DrupalWebTestCase::prepareDatabasePrefix protected function Generates a database prefix for running tests.
DrupalWebTestCase::prepareEnvironment protected function Prepares the current environment for running the test.
DrupalWebTestCase::recursiveDirectoryCopy protected function Recursively copy one directory to another.
DrupalWebTestCase::refreshVariables protected function Refresh the in-memory set of variables. Useful after a page request is made that changes a variable in a different thread. 1
DrupalWebTestCase::resetAll protected function Reset all data structures after having enabled new modules.
DrupalWebTestCase::storeSetupCache protected function Store the installation setup to a cache.
DrupalWebTestCase::tearDown protected function Delete created files and temporary files directory, delete the tables created by setUp(), and reset the database prefix. 6
DrupalWebTestCase::verboseEmail protected function Outputs to verbose the most recent $count emails sent.
DrupalWebTestCase::xpath protected function Perform an xpath search on the contents of the internal browser. The search is relative to the root element (HTML tag normally) of the page.
DrupalWebTestCase::__construct function Constructor for DrupalWebTestCase. Overrides DrupalTestCase::__construct 1