123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- <?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.");
- }
- }
|