field_permission_example.test in Examples for Developers 7
Tests for Field Permission Example.
File
field_permission_example/tests/field_permission_example.testView source
<?php
/**
* @file
* Tests for Field Permission Example.
*
* @ingroup field_permission_example
*/
/**
* A generic field testing class.
*
* Subclass this one to test your specific field type
* and get some basic unit testing for free.
*
* Since Simpletest only looks through one class definition
* to find test functions, we define generic tests as
* 'code_testWhatever' or 'form_testWhatever'. Subclasses
* can then implement shim test methods that just call the
* generic tests.
*
* 'code_' and 'form_' prefixes denote the type of test:
* using code only, or through Drupal page forms.
*
* @ingroup field_permission_example
*/
class GenericFieldTest extends DrupalWebTestCase {
// Our tests will generate some random field instance
// names. We store them here so many functions can act on them.
protected $instanceNames;
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Generic Field Test',
'description' => 'Someone neglected to override GenericFieldTest::getInfo().',
'group' => 'Examples',
);
}
/**
* Supply the field types we wish to test.
*
* Return an array of field types to instantiate and test.
*
* @return array
* The field types we wish to use.
*/
protected function getFieldTypes() {
return array(
'these_are_not',
'valid_field_types',
'please_override',
);
}
/**
* The module to enable.
*
* @return string
* Module machine name.
*/
protected function getModule() {
return 'this-is-not-a-module-name-please-override';
}
/**
* Simpletest's setUp().
*
* We want to be able to subclass this class, so we jump
* through a few hoops in order to get the modules from args
* and add our own.
*/
public function setUp() {
$this->instanceNames = array();
$modules = func_get_args();
if (isset($modules[0]) && is_array($modules[0])) {
$modules = $modules[0];
}
$modules[] = 'node';
$modules[] = 'field_ui';
parent::setUp($modules);
}
/**
* Verify that all required fields are specified in hook_field_info().
*
* The full list is label, description, settings, instance_settings,
* default_widget, default_formatter, no_ui.
*
* Some are optional, and we won't check for those.
*
* In a sane world, this would be a unit test, rather than a
* web test, but module_implements is unavailable to us
* in unit tests.
*
* @see hook_field_info()
*/
public function runTestGenericFieldInfo() {
$field_types = $this
->getFieldTypes();
$module = $this
->getModule();
$info_keys = array(
'label',
'description',
'default_widget',
'default_formatter',
);
// We don't want to use field_info_field_types()
// because there is a hook_field_info_alter().
// We're testing the module here, not the rest of
// the system. So invoke hook_field_info() ourselves.
$modules = module_implements('field_info');
$this
->assertTrue(in_array($module, $modules), 'Module ' . $module . ' implements hook_field_info()');
foreach ($field_types as $field_type) {
$field_info = module_invoke($module, 'field_info');
$this
->assertTrue(isset($field_info[$field_type]), 'Module ' . $module . ' defines field type ' . $field_type);
$field_info = $field_info[$field_type];
foreach ($info_keys as $key) {
$this
->assertTrue(isset($field_info[$key]), $field_type . "'s " . $key . ' is set.');
}
}
}
/**
* Add all testable fields as instances to a content type.
*
* As a side-effect: Store the names of the instances created
* in $this->$instance_names.
*
* @param object $node_type
* A content type object. If none is provided, one will be generated.
*
* @return object
* The content type object that has the fields attached.
*/
public function codeTestGenericAddAllFields($node_type = NULL) {
$this->instanceNames = array();
if (!$node_type) {
$node_type = $this
->drupalCreateContentType();
}
foreach ($this
->getFieldTypes() as $field_type) {
$instance_name = drupal_strtolower($this
->randomName(32));
$field = array(
'field_name' => $instance_name,
'type' => $field_type,
);
$field = field_create_field($field);
$instance = array(
'field_name' => $instance_name,
'entity_type' => 'node',
'bundle' => $node_type->name,
'label' => drupal_strtolower($this
->randomName(20)),
);
// Finally create the instance.
$instance = field_create_instance($instance);
// Reset the caches...
_field_info_collate_fields(TRUE);
// Grab this instance.
$verify_instance = field_info_instance('node', $instance_name, $node_type->name);
$this
->assertTrue($verify_instance, 'Instance object exists.');
$this
->assertTrue($verify_instance != NULL, 'field_info_instance() says ' . $instance_name . ' (' . $node_type->name . ') was created.');
$this->instanceNames[] = $instance_name;
}
return $node_type;
}
/**
* Remove all fields in $this->field_names.
*
* @param mixed $node_type
* A content type object. If none is specified,
* the test fails.
*/
public function codeTestGenericRemoveAllFields($node_type = NULL) {
if (!$node_type) {
$this
->fail('No node type.');
}
if (count($this->instanceNames) < 1) {
$this
->fail('There are no instances to remove.');
return;
}
foreach ($this->instanceNames as $instance_name) {
$instance = field_info_instance('node', $instance_name, $node_type->name);
$this
->assertTrue($instance, "Instance exists, now we'll delete it.");
field_delete_field($instance_name);
$instance = field_info_instance('node', $instance_name, $node_type->name);
$this
->assertFalse($instance, 'Instance was deleted.');
}
$this->instanceNames = array();
}
/**
* Add and delete all field types through Form API.
*
* @access public
*/
public function formTestGenericFieldNodeAddDeleteForm() {
// Create and login user.
$account = $this
->drupalCreateUser(array(
'administer content types',
'administer fields',
));
$this
->drupalLogin($account);
// Add a content type.
$node_type = $this
->drupalCreateContentType();
// Add all our testable fields.
$field_names = $this
->formAddAllFields($node_type);
// Now let's delete all the fields.
foreach ($field_names as $field_name) {
// This is the path for the 'delete' link on field admin page.
$this
->drupalGet('admin/structure/types/manage/' . $node_type->name . '/fields/field_' . $field_name . '/delete');
// Click the 'delete' button.
$this
->drupalPost(NULL, array(), t('Delete'));
$this
->assertText(t('The field @field has been deleted from the @type content type.', array(
'@field' => $field_name,
'@type' => $node_type->name,
)));
}
}
/**
* Add all fields using Form API.
*
* @param mixed $node_type
* A content type object. If none is specified,
* the test fails.
*/
protected function formAddAllFields($node_type = NULL) {
if (!$node_type) {
$this
->fail('No content type specified.');
}
// Get all our field types.
$field_types = $this
->getFieldTypes();
// Keep a list of no_ui fields so we can tell the user.
$unsafe_field_types = array();
$field_names = array();
$manage_path = 'admin/structure/types/manage/' . $node_type->name . '/fields';
foreach ($field_types as $field_type) {
// Get the field info.
$field_info = field_info_field_types($field_type);
// Exclude no_ui field types.
if (isset($field_info['no_ui']) && $field_info['no_ui']) {
$unsafe_field_types[] = $field_type;
}
else {
// Generate a name for our field.
// 26 is max length for field name.
$field_name = drupal_strtolower($this
->randomName(26));
$field_names[$field_type] = $field_name;
// Create the field through Form API.
$this
->formCreateField($manage_path, $field_type, $field_name, $field_info['default_widget'], 1);
}
}
// Tell the user which fields we couldn't test.
if (!empty($unsafe_field_types)) {
debug('Unable to attach these no_ui fields: ' . implode(', ', $unsafe_field_types));
}
// Somehow clicking "save" isn't enough, and we have to
// rebuild a few caches.
node_types_rebuild();
menu_rebuild();
return $field_names;
}
/**
* Create a field using the content type management form.
*
* @param mixed $manage_path
* Path to our content type management form.
* @param mixed $field_type
* The type of field we're adding.
* @param mixed $field_name
* The name of the field instance we want.
* @param mixed $widget_type
* Which widget would we like?
* @param mixed $cardinality
* Cardinality for this field instance.
*/
protected function formCreateField($manage_path, $field_type, $field_name, $widget_type, $cardinality) {
// $manage_path is the field edit form for our content type.
$this
->drupalGet($manage_path);
$edit = array(
'fields[_add_new_field][label]' => $field_name,
'fields[_add_new_field][field_name]' => $field_name,
'fields[_add_new_field][type]' => $field_type,
'fields[_add_new_field][widget_type]' => $widget_type,
);
$this
->drupalPost(NULL, $edit, t('Save'));
// Assume there are no settings for this,
// so just press the button.
$this
->drupalPost(NULL, array(), t('Save field settings'));
$edit = array(
'field[cardinality]' => (string) $cardinality,
);
$this
->drupalPost(NULL, $edit, t('Save settings'));
debug(t('Saved settings for field !field_name with widget !widget_type and cardinality !cardinality', array(
'!field_name' => $field_name,
'!widget_type' => $widget_type,
'!cardinality' => $cardinality,
)));
$this
->assertText(t('Saved @name configuration.', array(
'@name' => $field_name,
)));
}
/**
* Create a node with some field content.
*
* @return object
* Node object for the created node.
*/
public function createFieldContentForUser($account = NULL, $content = 'testable_content', $node_type = NULL, $instance_name = '', $column = NULL) {
if (!$column) {
$this
->fail('No column name given.');
return NULL;
}
if (!$account) {
$account = $this
->drupalCreateUser(array(
'bypass node access',
'administer content types',
));
}
$this
->drupalLogin($account);
if (!$node_type) {
$node_type = $this
->codeTestGenericAddAllFields();
}
if (!$instance_name) {
$instance_name = reset($this->instanceNames);
}
$field = array();
$field[LANGUAGE_NONE][0][$column] = $content;
$settings = array(
'type' => $node_type->name,
$instance_name => $field,
);
$node = $this
->drupalCreateNode($settings);
$this
->assertTrue($node, 'Node of type ' . $node->type . ' allegedly created.');
$node = node_load($node->nid);
debug('Loaded node id: ' . $node->nid);
$this
->assertTrue($node->{$instance_name}, 'Field actually created.');
$field = $node->{$instance_name};
$this
->assertTrue($field[LANGUAGE_NONE][0][$column] == $content, 'Content was stored properly on the field.');
return $node;
}
}
class FieldTestPermissionsExample extends GenericFieldTest {
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp(array(
'field_permission_example',
));
}
/**
* {@inheritdoc}
*/
public static function getInfo() {
return array(
'name' => 'Field Permission Example',
'description' => 'Various tests on the functionality of the Fieldnote field.',
'group' => 'Examples',
);
}
/**
* {@inheritdoc}
*/
protected function getFieldTypes() {
return array(
'field_permission_example_fieldnote',
);
}
/**
* {@inheritdoc}
*/
protected function getModule() {
return 'field_permission_example';
}
/**
* Override createFieldContentForUser().
*
* We override so we can make sure $column is set to 'notes'.
*/
public function createFieldContentForUser($account = NULL, $content = 'fieldnote_testable_content', $node_type = NULL, $instance_name = '', $column = 'notes') {
return parent::createFieldContentForUser($account, $content, $node_type, $instance_name, $column);
}
/**
* Test of hook_field_info() and other implementation requirements.
*
* @see GenericFieldTest::runTestGenericFieldInfo()
*/
public function testFieldnoteInfo() {
$this
->runTestGenericFieldInfo();
}
/**
* Add and remove the field through Form API.
*/
public function testAddRemoveFieldnoteForm() {
$this
->formTestGenericFieldNodeAddDeleteForm();
}
/**
* Add and remove the field through code.
*/
public function testAddRemoveFieldnoteCode() {
$node_type = $this
->codeTestGenericAddAllFields();
$this
->codeTestGenericRemoveAllFields($node_type);
}
/**
* Test view permissions.
*/
public function testFieldnoteViewPerms() {
// We create two sets of content so we can get a few
// test cases out of the way.
$view_own_content = $this
->randomName(23);
$view_any_content = $this
->randomName(23);
$view_own_node = $this
->createFieldContentForUser(NULL, $view_own_content);
// Get the type of the node so we can create another one.
$node_type = node_type_load($view_own_node->type);
$view_any_node = $this
->createFieldContentForUser(NULL, $view_any_content, $node_type);
// There should be a node now, with some lovely content, but it's the wrong
// user for the view-own test.
$view_own_account = $this
->drupalCreateUser(array(
'view own fieldnote',
));
debug("Created user with 'view own fieldnote' permission.");
// Now change the user id for the test node.
$view_own_node = node_load($view_own_node->nid);
$view_own_node->uid = $view_own_account->uid;
node_save($view_own_node);
$view_own_node = node_load($view_own_node->nid);
$this
->assertTrue($view_own_node->uid == $view_own_account->uid, 'New user assigned to node.');
// Now we want to look at the page with the field and
// check that we can see it.
$this
->drupalLogin($view_own_account);
$this
->drupalGet('node/' . $view_own_node->nid);
// Check that the field content is present.
$output_strings = $this
->xpath("//div[contains(@class,'stickynote')]/text()");
$this
->assertEqual((string) reset($output_strings), $view_own_content);
debug("'view own fieldnote' can view own field.");
// This account shouldn't be able to see the field on the
// 'view any' node.
$this
->drupalGet('node/' . $view_any_node->nid);
// Check that the field content is not present.
$output_strings = $this
->xpath("//div[contains(@class,'stickynote')]/text()");
$this
->assertNotEqual((string) reset($output_strings), $view_any_content);
debug("'view own fieldnote' cannot view other field.");
// Now, to test for 'view any fieldnote' we create another user
// with that permission, and try to look at the same node.
$view_any_account = $this
->drupalCreateUser(array(
'view any fieldnote',
));
debug("Created user with 'view any fieldnote' permission.");
$this
->drupalLogin($view_any_account);
// This account should be able to see the field on the
// 'view any' node.
$this
->drupalGet('node/' . $view_any_node->nid);
// Check that the field content is present.
$output_strings = $this
->xpath("//div[contains(@class,'stickynote')]/text()");
$this
->assertEqual((string) reset($output_strings), $view_any_content);
debug("'view any fieldnote' can view other field.");
}
/**
* Test edit permissions.
*
* Note that this is mostly identical to testFieldnoteViewPerms() and could
* probably be refactored.
*/
public function testFieldnoteEditPerms() {
// We create two sets of content so we can get a few
// test cases out of the way.
$edit_own_content = $this
->randomName(23);
$edit_any_content = $this
->randomName(23);
$edit_own_node = $this
->createFieldContentForUser(NULL, $edit_own_content);
// Get the type of the node so we can create another one.
$node_type = node_type_load($edit_own_node->type);
$edit_any_node = $this
->createFieldContentForUser(NULL, $edit_any_content, $node_type);
$edit_own_account = $this
->drupalCreateUser(array(
'edit own ' . $node_type->name . ' content',
'edit own fieldnote',
));
debug("Created user with 'edit own fieldnote' permission.");
// Now change the user id for the test node.
$edit_own_node = node_load($edit_own_node->nid);
$edit_own_node->uid = $edit_own_account->uid;
node_save($edit_own_node);
$edit_own_node = node_load($edit_own_node->nid);
$this
->assertTrue($edit_own_node->uid == $edit_own_account->uid, 'New edit test user assigned to node.');
// Now we want to look at the page with the field and
// check that we can see it.
$this
->drupalLogin($edit_own_account);
$this
->drupalGet('node/' . $edit_own_node->nid . '/edit');
$this
->assertText($edit_own_content, "'edit own fieldnote' can edit own fieldnote.");
// This account shouldn't be able to edit the field on the
// 'edit any' node.
$this
->drupalGet('node/' . $edit_any_node->nid . '/edit');
$this
->assertNoText($edit_any_content, "'edit own fieldnote' can not edit any fieldnote.");
// Now, to test for 'edit any fieldnote' we create another user
// with that permission, and try to edit at the same node.
// We have to add the ability to edit any node content, as well
// or Drupal will deny us access to the page.
$edit_any_account = $this
->drupalCreateUser(array(
'edit any ' . $node_type->name . ' content',
'edit any fieldnote',
));
debug("Created user with 'edit any fieldnote' permission.");
$this
->drupalLogin($edit_any_account);
// This account should be able to see the field on the
// 'edit any' node.
$this
->drupalGet('node/' . $edit_any_node->nid . '/edit');
$this
->assertText($edit_any_content, "'edit any fieldnote' can edit any fieldnote.");
}
}
Classes
Name | Description |
---|---|
FieldTestPermissionsExample | |
GenericFieldTest | A generic field testing class. |