function WorkbenchAccessMenuTestCase::testWorkbenchAccessMenu in Workbench Access 7
File
- tests/
workbench_access.test, line 433 - Test file for Workbench Access.
Class
Code
function testWorkbenchAccessMenu() {
// Load all includes.
workbench_access_load_include();
// Create some node and users.
$this
->createWorkbenchAccessUsers();
$this
->createWorkbenchAccessNodes(30);
// Set node titles for easier debugging.
for ($i = 1; $i <= 30; $i++) {
$node = node_load($i);
$node->title = $this->node_titles[$i];
node_save($node);
}
// Create a menu.
$menu = array(
'menu_name' => 'menu-workbench_access',
'description' => '',
'title' => $this
->randomName(16),
);
menu_save($menu);
$menu_name = $menu['menu_name'];
// Attach menu to content type.
variable_set('menu_options_page', array(
'menu_options[' . $menu_name . ']' => $menu_name,
));
// Make all menu items access sections.
variable_set('workbench_access_auto_assign', 1);
// Set this menu as our active section.
variable_set('workbench_access', 'menu');
variable_set('workbench_access_menu', array(
$menu_name,
));
// Use a custom form element.
variable_set('workbench_access_custom_form', 1);
// Set up the top-level menu.
$section = array(
'access_id' => $menu_name,
'access_scheme' => 'menu',
'access_type' => 'menu',
'access_type_id' => $menu_name,
);
workbench_access_section_save($section);
/**
* 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
*/
$mlids = array();
$nodes = db_query("SELECT nid, title FROM {node} ORDER BY nid")
->fetchAll();
foreach ($nodes as $nid => $node) {
// Create a menu item
$settings = array(
'link_path' => 'node/' . $node->nid,
'link_title' => $node->title,
'menu_name' => $menu_name,
'weight' => $node->nid,
'plid' => 0,
);
if ($nid > 1) {
$settings['plid'] = $mlids[floor(($nid - 2) / 2)];
}
$mlids[] = menu_link_save($settings);
}
// Check that the menu scheme is setup correctly.
$this
->assertWorkbenchScheme('menu', $menu_name);
// Check for node creation.
$count = db_query("SELECT COUNT(n.nid) FROM {node} n")
->fetchField();
$this
->assertTrue($count == 30, t('Thirty initial nodes created.'));
// Check for node assignment.
$count = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {workbench_access_node} wan ON n.nid = wan.nid")
->fetchField();
$this
->assertTrue($count == 0, t('Initial nodes have no access data.'));
// Save data for nodes.
foreach ($nodes as $node) {
$mlid = db_query("SELECT mlid FROM {menu_links} WHERE link_path = :link_path", array(
':link_path' => 'node/' . $node->nid,
))
->fetchField();
if (!isset($first_mlid)) {
$first_mlid = $mlid;
}
$edit = array(
'nid' => $node->nid,
'access_id' => $mlid,
'access_scheme' => 'menu',
);
db_insert('workbench_access_node')
->fields($edit)
->execute();
}
// Assign user 1 to the top-level.
workbench_access_user_section_save(1, $menu_name, 'menu');
// Check node data.
$count = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {workbench_access_node} wan ON n.nid = wan.nid")
->fetchField();
$this
->assertTrue($count == 30, t('Initial nodes assigned access data.'));
$active = workbench_access_get_active_tree();
// Check that a node has been assigned to a first-level menu item.
$count = db_query("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {workbench_access_node} wan ON n.nid = wan.nid WHERE wan.access_id = :access_id AND wan.access_scheme = 'menu'", array(
':access_id' => $first_mlid,
))
->fetchField();
$this
->assertTrue($count == 1, t('One node assigned to first-level menu item.'));
// 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).
$account = $this
->getWorkbenchAccessUser();
$id = $account->testId;
$this
->assertTrue(empty($account->workbench_access[$menu_name]), t('Test user not assigned to a section.'));
$nids = db_query("SELECT nid FROM {node}")
->fetchCol('nid');
$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
->assertWorkbenchAccessCheck($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
->assertWorkbenchAccessCheck($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
->assertWorkbenchAccessCheck($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('One 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
->assertWorkbenchAccessCheck($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.
$test_account = $this
->getWorkbenchAccessUser($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 page content',
'edit any page content',
'delete any page content',
);
user_role_revoke_permissions($this->editor_role, $perms);
$account = user_load($account->uid, TRUE);
$this
->assertWorkbenchAccessCheck($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
->assertWorkbenchAccessCheck($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.'));
// 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.'));
// 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']) == 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, $menu_name, 'menu');
// Add sub permission.
$array = array_slice($active['tree'][$menu_name]['children'], 0, 1);
$mlid = array_shift($array);
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']) == 15, t('Form element returned fifteen options to user with limited options.'));
// Test the form again using native support.
// Do not set a custom form element.
variable_set('workbench_access_custom_form', 0);
$custom = variable_get('workbench_access_custom_form', 1);
$this
->assertTrue(empty($custom), t('Switched to using native menu form.'));
// Try some form introspection.
$form = $this
->workbenchAccessNodeForm($account->uid, $node->type);
$this
->assertTrue(count($form['menu']['link']['parent']['#options']) == 15, t('Native menu 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,
)));
// 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.'));
// 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.');
// Tests access per menu levels. We have structured our menu so that we
// know what these results should return.
// Test another user who is currently not assigned.
$account = $this
->getWorkbenchAccessUser($id);
// @todo: This is pretty obtuse. Can we improve it?
// @params are $account, $nid, $depth, $expected_count.
// See the map in the large docblock at the top of this test.
$this
->assertMenuUpdateNodes($account, 1, 1, 15);
$this
->assertMenuUpdateNodes($account, 3, 2, 7);
$this
->assertMenuUpdateNodes($account, 7, 3, 3);
$this
->assertMenuUpdateNodes($account, 15, 4, 1);
// Test for issue #1203260. Some menu links cause fatal error.
// Make all menu items access sections.
variable_set('workbench_access_auto_assign', 1);
// Create a menu item that triggers the failure, which is based on access
// checks for menu links while we are fetching our raw tree.
$link = array(
'link_path' => 'node/add',
'link_title' => 'Add content',
'menu_name' => $menu_name,
'weight' => 0,
'plid' => 0,
);
menu_link_save($link);
// Bug is triggered by anonymous users building the cache.
$this
->drupalLogout();
workbench_access_reset_tree();
// Check that the menu scheme is setup correctly.
drupal_flush_all_caches();
$this
->drupalGet('node');
// If we hit an infinite loop, the page does not return listings.
// Note the HTML fragent here, which assures success on various installs.
$this
->assertRaw('node/30">B2b2</a>', t('Node listing page returns properly.'));
$this
->assertWorkbenchScheme('menu', $menu_name);
}