diff --git a/tests/workbench_access.test b/tests/workbench_access.test
index d4d56af..fb38f9c 100644
--- a/tests/workbench_access.test
+++ b/tests/workbench_access.test
@@ -5,15 +5,15 @@
  * Test file for Workbench Access.
  */
 
-class WorkbenchAccessTestCase extends DrupalWebTestCase {
+class WorkbenchAccessTaxonomyTestCase extends DrupalWebTestCase {
   protected $user_list;
   protected $editor_role;
   protected $permissions;
 
   public static function getInfo() {
     return array(
-      'name' => 'Workbench access controls',
-      'description' => 'Test access control rules for Workbench Access.',
+      'name' => 'Taxonomy access controls',
+      'description' => 'Test access control rules for Workbench Access using the Taxonomy access scheme.',
       'group' => 'Workbench Access'
     );
   }
@@ -51,28 +51,6 @@ class WorkbenchAccessTestCase extends DrupalWebTestCase {
     }
   }
 
-  /**
-   * Helper function for form introspection.
-   *
-   * Forms are sensitive to the global user account, so we must reset it when
-   * using this technique.
-   *
-   * @param $uid
-   *   A user id representing the account to test.
-   * @param $type
-   *   The node type of the form.
-   */
-  public function workbenchAccessNodeForm($uid, $type) {
-    $temp = $GLOBALS['user'];
-    $user = user_load($uid, TRUE);
-    $GLOBALS['user'] = $user;
-    $node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
-    module_load_include('inc', 'node', 'node.pages');
-    $form = drupal_get_form($type . '_node_form', $node);
-    $GLOBALS['user'] = $temp;
-    return $form;
-  }
-
   // Base test for installation.
   function testWorkbenchAccess() {
     // Check for user creation.
@@ -227,17 +205,434 @@ class WorkbenchAccessTestCase extends DrupalWebTestCase {
     $this->assertRaw('TestWA', t('Workbench Access field was renamed.'));
     $this->assertRaw('<select multiple="multiple" name="workbench_access[]" id="edit-workbench-access--2" class="form-select required">', t('Form presents a select list with multiple select.'));
 
+    // Check that access control by node type settings work.
+    $this->assertTrue(variable_get('workbench_access_node_type_' . $node->type, 1), t('Workbench Access enforced for %type content.', array('%type' => $node->type)));
+    // Force a fail by removing this user's access rules. Else it will just
+    // return NODE_ACCESS_IGNORE, which cannot be tested.
+    $account->workbench_access = array('foo');
+    $response = workbench_access_node_access($node, 'update', $account);
+    $this->assertTrue($response == NODE_ACCESS_DENY, t('Workbench Access rules enforced on test node.'));
+
+    // Since the user is not in a section, this should DENY, unless the node
+    // type is ignored.
+
+    // Test for ignore.
+    variable_set('workbench_access_node_type_' . $node->type, 0);
+    $this->assertFalse(variable_get('workbench_access_node_type_' . $node->type, 1), t('Workbench Access not enforced for %type content.', array('%type' => $node->type)));
+    $response = workbench_access_node_access($node, 'update', $account);
+    $this->assertTrue($response == NODE_ACCESS_IGNORE, t('Workbench Access rules ignored on test node.'));
+    // Test for deny.
+    variable_set('workbench_access_node_type_' . $node->type, 1);
+    $this->assertTrue(variable_get('workbench_access_node_type_' . $node->type, 1), t('Workbench Access enforced for %type content.', array('%type' => $node->type)));
+    $response = workbench_access_node_access($node, 'update', $account);
+    $this->assertTrue($response == NODE_ACCESS_DENY, t('Workbench Access rules enforced on test node.'));
+
+    // If the node is not assigned, we should ignore.
+    $temp = $node->workbench_access;
+    $node->workbench_access = array();
+    $response = workbench_access_node_access($node, 'update', $account);
+    $this->assertTrue($response == NODE_ACCESS_IGNORE, t('Workbench Access rules ignored for unassigned node.'));
+    // Make sure the above was not a false positive.
+    $node->workbench_access = $temp;
+    $response = workbench_access_node_access($node, 'update', $account);
+    $this->assertTrue($response == NODE_ACCESS_DENY, t('Workbench Access rules enforced on test node.'));
+
+    // Restore the account, in case we do more tests later.
+    $account = user_load($account->uid, TRUE);
+
+    // Delete the user account.
+    user_delete($account->uid);
+    $records = db_query("SELECT 1 FROM {workbench_access_user} WHERE uid = :uid", array(':uid' => $account->uid))->fetchField();
+    $this->assertFalse($records, 'User section assignments removed.');
+
+    // Test module hooks.
+    // Ensure that our node type uses the form element.
+    $GLOBALS['conf']['workbench_access_node_type_' . $node->type] = TRUE;
+    $form = drupal_get_form($node->type . '_node_form', $node);
+    $this->assertTrue(!empty($form['workbench_access']['workbench_access']['#workbench_access_test']), t('hook_workbench_access_node_element_alter() fired correctly.'));
+  }
+
+  /**
+   * Simple method for running the same node access checks repeatedly.
+   *
+   * @param $nodes
+   *  The nodes to check. If one fails, the test fails.
+   * @param $account
+   *  The user account being tested.
+   * @param $message
+   *  The string to prefix in front of the test result message.
+   * @param $true
+   *  Boolean indicator that we want to test TRUE or FALSE on this test.
+   */
+  function workbench_access_action_check($nodes, $account, $message, $true = TRUE) {
+    // Since we change conditions, reset node access.
+    drupal_static_reset('node_access');
+    // Check the node operations.
+    $actions = array('create', 'update', 'delete');
+    foreach ($actions as $action) {
+      foreach ($nodes as $node) {
+        $status[$action] = FALSE;
+        if ($action == 'create') {
+          $result = node_access($action, $node->type, $account);
+        }
+        else {
+          $result = node_access($action, $node, $account);
+        }
+        if ($result) {
+          $status[$action] = TRUE;
+          break;
+        }
+      }
+      if ($true) {
+        $this->assertTrue(!empty($status[$action]), t('@message. Test user can @action content.', array('@message' => $message, '@action' => $action)));
+      }
+      else {
+        $this->assertTrue(empty($status[$action]), t('@message. Test user cannot @action content.', array('@message' => $message, '@action' => $action)));
+      }
+    }
+  }
+}
+
+class WorkbenchAccessMenuTestCase extends DrupalWebTestCase {
+  protected $user_list;
+  protected $editor_role;
+  protected $permissions;
+  protected $profile = 'minimal';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Menu access controls',
+      'description' => 'Test access control rules for Workbench Access using the Menu access scheme.',
+      'group' => 'Workbench Access'
+    );
+  }
+
+  function setUp() {
+    parent::setUp(array('workbench_access', 'workbench_access_test', 'menu', 'taxonomy'));
+    // Create a page content type
+    $this->content_type = $this->drupalCreateContentType();
+
+    // Admin user for submissions
+    $perms = array_keys(module_invoke_all('permission'));
+    $this->admin_user = $this->drupalCreateUser($perms);
+    $this->drupalLogin($this->admin_user);
+
+    // Add an editor role.
+    $perms = array(
+      'access content',
+      'access workbench access by role',
+      'create ' . $this->content_type->type . ' content',
+      'edit any ' . $this->content_type->type . ' content',
+      'delete any ' . $this->content_type->type . ' content',
+    );
+    $this->editor_role = $this->drupalCreateRole($perms);
+
+    // Create users.
+    for ($i = 0; $i < 10; $i++) {
+      // Using drupalCreateUser runs tests we don't want.
+      $edit = array(
+        'name' => $this->randomName(32),
+        'mail' => $this->randomName(32) . '@example.com',
+        'roles' => drupal_map_assoc(array(DRUPAL_AUTHENTICATED_RID, $this->editor_role)),
+        'status' => 1,
+        'pass' => 'fubar',
+      );
+      $this->user_list[] = user_save(NULL, $edit);
+    }
+  }
+
+  /**
+   * Helper function for form introspection.
+   *
+   * Forms are sensitive to the global user account, so we must reset it when
+   * using this technique.
+   *
+   * @param $uid
+   *   A user id representing the account to test.
+   * @param $type
+   *   The node type of the form.
+   */
+  public function workbenchAccessNodeForm($uid, $type) {
+    $temp = $GLOBALS['user'];
+    $user = user_load($uid, TRUE);
+    $GLOBALS['user'] = $user;
+    $node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
+    module_load_include('inc', 'node', 'node.pages');
+    $form = drupal_get_form($type . '_node_form', $node);
+    $GLOBALS['user'] = $temp;
+    return $form;
+  }
+
+  // Base test for installation.
+  function testWorkbenchAccess() {
+    // Check for user creation.
+    $this->assertTrue(count($this->user_list) == 10, t('Ten new users were created.'));
+    $this->assertTrue(!empty($this->editor_role), t('Created editor role.'));
+
+    // Create a new menu to put items into
+    $menu_name = substr(hash('sha256', $this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI - 10);
+    $edit = array(
+      'menu_name' => $menu_name,
+      'description' => '',
+      'title' =>  $this->randomName(16),
+    );
+    $this->drupalPost('admin/structure/menu/add', $edit, t('Save'));
+    $menu_name = 'menu-' . $menu_name;
+
+    // Attach menu to content type
+    $edit = array(
+      'menu_options[' . $menu_name . ']' => $menu_name,
+    );
+
+    $this->drupalPost('admin/structure/types/manage/' . $this->content_type->type, $edit, t('Save content type'));
+
+    // Create nodes
+    $nodes = array();
+    for ($i = 0; $i < 30; $i++) {
+      $node = $this->drupalCreateNode(array('type' => $this->content_type->type));
+      $nodes[] = $node;
+    }
+
+    /**
+     * Assign menu links for nodes.
+     * The hierarchy should four levels deep with two options per level
+     * A helpful diagram
+     *
+     * A
+     *   A1
+     *     A1a
+     *        A1a1
+     *        A1a2
+     *     A1b
+     *        A1b1
+     *        A1b2
+     *   A2
+     *     A2a
+     *        A2a1
+     *        A2a2
+     *     A2b
+     *        A2b1
+     *        A2b2
+     * B
+     *   B1
+     *     B1a
+     *        B1a1
+     *        B1a2
+     *     B1b
+     *        B1b1
+     *        B1b2
+     *   B2
+     *     B2a
+     *        B2a1
+     *        B2a2
+     *     B2b
+     *        B2b1
+     *        B2b2
+     */
+    $items = array();
+    foreach ($nodes as $id => $node) {
+      // Create a menu item
+      $settings = array(
+        'link_path' => 'node/' . $node->nid,
+        'link_title' => $node->title,
+        'menu_name' => $menu_name,
+        'weight' => $node->nid,
+      );
+
+      if ($id > 1) {
+        $settings['plid'] = $items[floor(($id - 2) / 2)];
+      }
+
+      $items[$id] = menu_link_save($settings);
+    }
+
+    // Check for node creation.
+    $count = db_select('node', 'n')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+    $this->assertTrue($count == 30, t('Thirty initial nodes created.'));
+
+    $query = db_select('node', 'n');
+    $query->join('workbench_access_node', 'wan', 'n.nid = wan.nid');
+    $count = $query->countQuery()
+      ->execute()
+      ->fetchField();
+    $this->assertTrue($count == 0, t('Initial nodes have no access data.'));
+
+    // Enable Menu Workbench access
+    $edit = array(
+      'workbench_access' => 'menu',
+      'workbench_access_menu[' . $menu_name . ']' => array($menu_name),
+      'workbench_access_custom_form' => TRUE,
+    );
+    $this->drupalPost('admin/config/workbench/access/settings', $edit, t('Save configuration'));
+
+    foreach ($nodes as $id => $node) {
+      $plid = db_select('menu_links', 'ml')
+        ->fields('ml', array('plid'))
+        ->condition('mlid', $items[$id])
+        ->execute()
+        ->fetchField();
+
+      $edit = array(
+        'nid' => $node->nid,
+        'access_id' => ($plid != 0 ? $plid : $menu_name),
+        'access_scheme' => 'menu',
+      );
+      db_insert('workbench_access_node')
+        ->fields($edit)
+        ->execute();
+    }
+    workbench_access_user_section_save(1, $menu_name, 'menu');
+
+    $query = db_select('node', 'n');
+    $query->join('workbench_access_node', 'wan', 'n.nid = wan.nid');
+    $count = $query->countQuery()
+      ->execute()
+      ->fetchField();
+    $this->assertTrue($count == 30, t('Initial nodes assigned access data.'));
+
+    // Check that the vocabulary is setup correctly.
+    workbench_access_reset_tree();
+    $active = workbench_access_get_active_tree();
+    $this->assertTrue(!empty($active['access_scheme']), t('Active access scheme set.'));
+    $this->assertTrue(!empty($active['tree']), t('Active access tree set.'));
+    $this->assertTrue(!empty($active['active']), t('Active access sections set.'));
+    $this->assertTrue($active['access_scheme']['access_scheme'] == 'menu', t('Using menu access scheme.'));
+    $this->assertTrue(isset($active['access_scheme']['access_type_id'][$menu_name]), t('Using Workbench Access test vocabulary.'));
+    $this->assertTrue(isset($active['tree'][$menu_name]), t('Vocabulary tree returned correctly.'));
+    // Check that nodes have been assigned to the top-level item.
+    $query = db_select('node', 'n');
+    $query->join('workbench_access_node', 'wan', 'n.nid = wan.nid');
+    $count = $query->condition('wan.access_id', $menu_name)
+      ->condition('wan.access_scheme', 'menu')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+
+    $this->assertTrue($count == 2, t('Initial nodes assigned to top-level hierarchy.'));
+    // Test access settings of user 1.
+    $account = user_load(1, TRUE);
+    $this->assertTrue(!empty($account->workbench_access[$menu_name]), t('User 1 assigned to top-level hierarchy.'));
+    // End setup tests.
+
+    // Assign a user to a section and check permissions.
+    // This is a multi-step check.
+    // First, the user should not be able to do anything (Create, Update or Delete).
+    $id = array_rand($this->user_list);
+    $account = $this->user_list[$id];
+    $this->assertTrue(empty($account->workbench_access[$menu_name]), t('Test user not assigned to a section.'));
+
+    $nids = db_select('node', 'n')
+      ->fields('n', array('nid'))
+      ->execute()
+      ->fetchCol();
+    $nodes = node_load_multiple($nids);
+    $assigned = TRUE;
+    foreach ($nodes as $node) {
+      // Just check if its set or not
+      if (!isset($node->workbench_access) && !empty($node->workbench_access)) {
+        $assigned = FALSE;
+      }
+    }
+    $this->assertTrue(!empty($assigned), t('All nodes properly assigned.'));
+    $this->workbench_access_action_check($nodes, $account, t('No sections'), FALSE);
+
+    // Test that the role lookup function works correctly.
+    $roles = workbench_access_get_roles('access workbench access by role');
+    // The 'administrator' role always has permission.
+    $this->assertTrue(count($roles) == 2, t('One user role assigned.'));
+
+    // Now, we assign the user to a section and check again.
+    workbench_access_user_section_save($account->uid, $menu_name, 'menu');
+    $account = user_load($account->uid, TRUE);
+    $this->assertTrue(!empty($account->workbench_access[$menu_name]), t('Test user assigned to top-level hierarchy.'));
+    $this->workbench_access_action_check($nodes, $account, t('Assigned sections'), TRUE);
+
+    // Remove the permission to 'access workbench access by role' and check again.
+    user_role_revoke_permissions($this->editor_role, array('access workbench access by role'));
+    $account = user_load($account->uid, TRUE);
+    $this->assertTrue(empty($account->workbench_access[$menu_name]), t('Permission revoked and test user not assigned to a section.'));
+    $this->workbench_access_action_check($nodes, $account, t('Role disallowed'), FALSE);
+
+    // Test that the role lookup function works correctly.
+    drupal_static_reset('workbench_access_get_roles');
+    $roles = workbench_access_get_roles('access workbench access by role');
+    // The 'administrator' role always has permission. Ignore that.
+    $this->assertTrue(count($roles) == 1, t('No user roles assigned.'));
+
+    // Now give them permissions again.
+    user_role_grant_permissions($this->editor_role, array('access workbench access by role'));
+    $account = user_load($account->uid, TRUE);
+    $this->assertTrue(!empty($account->workbench_access[$menu_name]), t('Permission reinstated and test user assigned to a section.'));
+    $this->workbench_access_action_check($nodes, $account, t('Role allowed'), TRUE);
+
+    // Test the autocomplete query for adding new editors.
+    drupal_static_reset('workbench_access_get_roles');
+    module_load_include('inc', 'workbench_access', 'workbench_access.pages');
+    // Search for the existing user via autocomplete. Should return empty.
+    $test = workbench_access_autocomplete('menu', $menu_name, substr($account->name, 0), TRUE);
+    $this->assertTrue(empty($test), t('Autocomplete did not match assigned user.'));
+    // Test another user who is currently not assigned.
+    if ($id < (count($this->user_list) - 1)) {
+      $id++;
+    }
+    else {
+      $id--;
+    }
+    $test_account = $this->user_list[$id];
+    $test = workbench_access_autocomplete('menu', $menu_name, substr($test_account->name, 0, 1), TRUE);
+    $this->assertTrue(!empty($test), t('Autocomplete matched unassigned user.'));
+
+    // Now take away the core permissions to page content and test.
+    $perms = array(
+      'create ' . $this->content_type->type . ' content',
+      'edit any ' . $this->content_type->type . ' content',
+      'delete any ' . $this->content_type->type . ' content',
+    );
+    user_role_revoke_permissions($this->editor_role, $perms);
+    $account = user_load($account->uid, TRUE);
+    $this->workbench_access_action_check($nodes, $account, t('Page access disallowed'), FALSE);
+
+    // Now give back the core permissions.
+    user_role_grant_permissions($this->editor_role, $perms);
+    $account = user_load($account->uid, TRUE);
+    $this->workbench_access_action_check($nodes, $account, t('Page access allowed'), TRUE);
+
+    // Form testing in Drupal is horribly broken.
+    // We can confirm that a form page is loaded, but cannot perform
+    // any introspection on the $form array.
+    $account->pass_raw = 'fubar';
+    $this->drupalLogin($account);
+    // Set the form label.
+    // Attempt to access edit page.
+    $this->drupalGet("node/$node->nid/edit");
+    $this->assertResponse(200);
+    $this->assertRaw('Section', t('Workbench Access field was found.'));
+    // Note that the field is nested as
+    // $form['workbench_access']['workbench_access'], which forces FormAPI to
+    // add the --2 suffix to the id.
+    $this->assertRaw('<select id="edit-workbench-access--2" name="workbench_access" class="form-select required">', t('Form presents a select list with no multiple select.'));
+    // Change some values and try again.
+    variable_set('workbench_access_allow_multiple', 1);
+    variable_set('workbench_access_label', 'TestWA');
+    $this->drupalGet("node/$node->nid/edit");
+    $this->assertRaw('TestWA', t('Workbench Access field was renamed.'));
+    $this->assertRaw('<select multiple="multiple" name="workbench_access[]" id="edit-workbench-access--2" class="form-select required">', t('Form presents a select list with multiple select.'));
+
     // Try some form introspection.
     $form = $this->workbenchAccessNodeForm($account->uid, $node->type);
     $this->assertTrue(isset($form['workbench_access']['workbench_access']['#options']), t('Form element returns properly.'));
-    $this->assertTrue(count($form['workbench_access']['workbench_access']['#options']) == 10, t('Form element returned ten options to user with all sections.'));
+    $this->assertTrue(count($form['workbench_access']['workbench_access']['#options']) == 31, t('Form element returned thirty-one options (top menu and thirty nodes) to user with all sections.'));
     // Delete global permission.
-    workbench_access_user_section_delete($account->uid, 'workbench_access', 'taxonomy');
+    workbench_access_user_section_delete($account->uid, $menu_name, 'menu');
     // Add sub permission.
-    $term = taxonomy_term_load(1);
-    workbench_access_user_section_save($account->uid, $term->tid, 'taxonomy');
+    $mlid = array_shift(array_slice($active['tree'][$menu_name]['children'], 0, 1));
+    workbench_access_user_section_save($account->uid, $mlid, 'menu');
+
     $form = $this->workbenchAccessNodeForm($account->uid, $node->type);
-    $this->assertTrue(count($form['workbench_access']['workbench_access']['#options']) == 3, t('Form element returned three options to user with limited options.'));
+    $this->assertTrue(count($form['workbench_access']['workbench_access']['#options']) == 15, t('Form element returned fifteen options to user with limited options.'));
 
     // Check that access control by node type settings work.
     $this->assertTrue(variable_get('workbench_access_node_type_' . $node->type, 1), t('Workbench Access enforced for %type content.', array('%type' => $node->type)));
@@ -273,12 +668,17 @@ class WorkbenchAccessTestCase extends DrupalWebTestCase {
 
     // Delete the user account.
     user_delete($account->uid);
-    $records = db_query("SELECT 1 FROM {workbench_access_user} WHERE uid = :uid", array(':uid' => $account->uid))->fetchField();
+    $records = db_select('workbench_access_user', 'wau')
+      ->condition('uid', $account->uid)
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertFalse($records, 'User section assignments removed.');
 
     // Test module hooks.
     // Ensure that our node type uses the form element.
     $GLOBALS['conf']['workbench_access_node_type_' . $node->type] = TRUE;
+    module_load_include('inc', 'node', 'node.pages');
     $form = drupal_get_form($node->type . '_node_form', $node);
     $this->assertTrue(!empty($form['workbench_access']['workbench_access']['#workbench_access_test']), t('hook_workbench_access_node_element_alter() fired correctly.'));
   }
