summaryrefslogtreecommitdiff
path: root/kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test
diff options
context:
space:
mode:
Diffstat (limited to 'kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test')
-rw-r--r--kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test751
1 files changed, 751 insertions, 0 deletions
diff --git a/kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test b/kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test
new file mode 100644
index 0000000..21767d6
--- /dev/null
+++ b/kolab.org/www/drupal-7.26/modules/field_ui/field_ui.test
@@ -0,0 +1,751 @@
+<?php
+
+/**
+ * @file
+ * Tests for field_ui.module.
+ */
+
+/**
+ * Provides common functionality for the Field UI test classes.
+ */
+class FieldUITestCase extends DrupalWebTestCase {
+
+ function setUp() {
+ // Since this is a base class for many test cases, support the same
+ // flexibility that DrupalWebTestCase::setUp() has for the modules to be
+ // passed in as either an array or a variable number of string arguments.
+ $modules = func_get_args();
+ if (isset($modules[0]) && is_array($modules[0])) {
+ $modules = $modules[0];
+ }
+ $modules[] = 'field_test';
+ parent::setUp($modules);
+
+ // Create test user.
+ $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
+ $this->drupalLogin($admin_user);
+
+ // Create content type, with underscores.
+ $type_name = strtolower($this->randomName(8)) . '_test';
+ $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
+ $this->type = $type->type;
+ // Store a valid URL name, with hyphens instead of underscores.
+ $this->hyphen_type = str_replace('_', '-', $this->type);
+ }
+
+ /**
+ * Creates a new field through the Field UI.
+ *
+ * @param $bundle_path
+ * Admin path of the bundle that the new field is to be attached to.
+ * @param $initial_edit
+ * $edit parameter for drupalPost() on the first step ('Manage fields'
+ * screen).
+ * @param $field_edit
+ * $edit parameter for drupalPost() on the second step ('Field settings'
+ * form).
+ * @param $instance_edit
+ * $edit parameter for drupalPost() on the third step ('Instance settings'
+ * form).
+ */
+ function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) {
+ // Use 'test_field' field type by default.
+ $initial_edit += array(
+ 'fields[_add_new_field][type]' => 'test_field',
+ 'fields[_add_new_field][widget_type]' => 'test_field_widget',
+ );
+ $label = $initial_edit['fields[_add_new_field][label]'];
+ $field_name = $initial_edit['fields[_add_new_field][field_name]'];
+
+ // First step : 'Add new field' on the 'Manage fields' page.
+ $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
+ $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), 'Field settings page was displayed.');
+
+ // Second step : 'Field settings' form.
+ $this->drupalPost(NULL, $field_edit, t('Save field settings'));
+ $this->assertRaw(t('Updated field %label field settings.', array('%label' => $label)), 'Redirected to instance and widget settings page.');
+
+ // Third step : 'Instance settings' form.
+ $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+ $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), 'Redirected to "Manage fields" page.');
+
+ // Check that the field appears in the overview form.
+ $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, 'Field was created and appears in the overview page.');
+ }
+
+ /**
+ * Adds an existing field through the Field UI.
+ *
+ * @param $bundle_path
+ * Admin path of the bundle that the field is to be attached to.
+ * @param $initial_edit
+ * $edit parameter for drupalPost() on the first step ('Manage fields'
+ * screen).
+ * @param $instance_edit
+ * $edit parameter for drupalPost() on the second step ('Instance settings'
+ * form).
+ */
+ function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) {
+ // Use 'test_field_widget' by default.
+ $initial_edit += array(
+ 'fields[_add_existing_field][widget_type]' => 'test_field_widget',
+ );
+ $label = $initial_edit['fields[_add_existing_field][label]'];
+ $field_name = $initial_edit['fields[_add_existing_field][field_name]'];
+
+ // First step : 'Add existing field' on the 'Manage fields' page.
+ $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
+
+ // Second step : 'Instance settings' form.
+ $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+ $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), 'Redirected to "Manage fields" page.');
+
+ // Check that the field appears in the overview form.
+ $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, 'Field was created and appears in the overview page.');
+ }
+
+ /**
+ * Deletes a field instance through the Field UI.
+ *
+ * @param $bundle_path
+ * Admin path of the bundle that the field instance is to be deleted from.
+ * @param $field_name
+ * The name of the field.
+ * @param $label
+ * The label of the field.
+ * @param $bundle_label
+ * The label of the bundle.
+ */
+ function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_label) {
+ // Display confirmation form.
+ $this->drupalGet("$bundle_path/fields/$field_name/delete");
+ $this->assertRaw(t('Are you sure you want to delete the field %label', array('%label' => $label)), 'Delete confirmation was found.');
+
+ // Submit confirmation form.
+ $this->drupalPost(NULL, array(), t('Delete'));
+ $this->assertRaw(t('The field %label has been deleted from the %type content type.', array('%label' => $label, '%type' => $bundle_label)), 'Delete message was found.');
+
+ // Check that the field does not appear in the overview form.
+ $this->assertNoFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, 'Field does not appear in the overview page.');
+ }
+}
+
+/**
+ * Tests the functionality of the 'Manage fields' screen.
+ */
+class FieldUIManageFieldsTestCase extends FieldUITestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Manage fields',
+ 'description' => 'Test the Field UI "Manage fields" screen.',
+ 'group' => 'Field UI',
+ );
+ }
+
+ function setUp() {
+ parent::setUp();
+
+ // Create random field name.
+ $this->field_label = $this->randomName(8);
+ $this->field_name_input = strtolower($this->randomName(8));
+ $this->field_name = 'field_'. $this->field_name_input;
+ }
+
+ /**
+ * Runs the field CRUD tests.
+ *
+ * In order to act on the same fields, and not create the fields over and over
+ * again the following tests create, update and delete the same fields.
+ */
+ function testCRUDFields() {
+ $this->manageFieldsPage();
+ $this->createField();
+ $this->updateField();
+ $this->addExistingField();
+ }
+
+ /**
+ * Tests the manage fields page.
+ */
+ function manageFieldsPage() {
+ $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields');
+ // Check all table columns.
+ $table_headers = array(
+ t('Label'),
+ t('Machine name'),
+ t('Field type'),
+ t('Widget'),
+ t('Operations'),
+ );
+ foreach ($table_headers as $table_header) {
+ // We check that the label appear in the table headings.
+ $this->assertRaw($table_header . '</th>', format_string('%table_header table header was found.', array('%table_header' => $table_header)));
+ }
+
+ // "Add new field" and "Add existing field" aren't a table heading so just
+ // test the text.
+ foreach (array('Add new field', 'Add existing field') as $element) {
+ $this->assertText($element, format_string('"@element" was found.', array('@element' => $element)));
+ }
+ }
+
+ /**
+ * Tests adding a new field.
+ *
+ * @todo Assert properties can bet set in the form and read back in $field and
+ * $instances.
+ */
+ function createField() {
+ // Create a test field.
+ $edit = array(
+ 'fields[_add_new_field][label]' => $this->field_label,
+ 'fields[_add_new_field][field_name]' => $this->field_name_input,
+ );
+ $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
+
+ // Assert the field appears in the "add existing field" section for
+ // different entity types; e.g. if a field was added in a node entity, it
+ // should also appear in the 'taxonomy term' entity.
+ $vocabulary = taxonomy_vocabulary_load(1);
+ $this->drupalGet('admin/structure/taxonomy/' . $vocabulary->machine_name . '/fields');
+ $this->assertTrue($this->xpath('//select[@name="fields[_add_existing_field][field_name]"]//option[@value="' . $this->field_name . '"]'), 'Existing field was found in account settings.');
+ }
+
+ /**
+ * Tests editing an existing field.
+ */
+ function updateField() {
+ // Go to the field edit page.
+ $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $this->field_name);
+
+ // Populate the field settings with new settings.
+ $string = 'updated dummy test string';
+ $edit = array(
+ 'field[settings][test_field_setting]' => $string,
+ 'instance[settings][test_instance_setting]' => $string,
+ 'instance[widget][settings][test_widget_setting]' => $string,
+ );
+ $this->drupalPost(NULL, $edit, t('Save settings'));
+
+ // Assert the field settings are correct.
+ $this->assertFieldSettings($this->type, $this->field_name, $string);
+
+ // Assert redirection back to the "manage fields" page.
+ $this->assertText(t('Saved @label configuration.', array('@label' => $this->field_label)), 'Redirected to "Manage fields" page.');
+ }
+
+ /**
+ * Tests adding an existing field in another content type.
+ */
+ function addExistingField() {
+ // Check "Add existing field" appears.
+ $this->drupalGet('admin/structure/types/manage/page/fields');
+ $this->assertRaw(t('Add existing field'), '"Add existing field" was found.');
+
+ // Check that the list of options respects entity type restrictions on
+ // fields. The 'comment' field is restricted to the 'comment' entity type
+ // and should not appear in the list.
+ $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value="comment"]'), 'The list of options respects entity type restrictions.');
+
+ // Add a new field based on an existing field.
+ $edit = array(
+ 'fields[_add_existing_field][label]' => $this->field_label . '_2',
+ 'fields[_add_existing_field][field_name]' => $this->field_name,
+ );
+ $this->fieldUIAddExistingField("admin/structure/types/manage/page", $edit);
+ }
+
+ /**
+ * Asserts field settings are as expected.
+ *
+ * @param $bundle
+ * The bundle name for the instance.
+ * @param $field_name
+ * The field name for the instance.
+ * @param $string
+ * The settings text.
+ * @param $entity_type
+ * The entity type for the instance.
+ */
+ function assertFieldSettings($bundle, $field_name, $string = 'dummy test string', $entity_type = 'node') {
+ // Reset the fields info.
+ field_info_cache_clear();
+ // Assert field settings.
+ $field = field_info_field($field_name);
+ $this->assertTrue($field['settings']['test_field_setting'] == $string, 'Field settings were found.');
+
+ // Assert instance and widget settings.
+ $instance = field_info_instance($entity_type, $field_name, $bundle);
+ $this->assertTrue($instance['settings']['test_instance_setting'] == $string, 'Field instance settings were found.');
+ $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, 'Field widget settings were found.');
+ }
+
+ /**
+ * Tests that default value is correctly validated and saved.
+ */
+ function testDefaultValue() {
+ // Create a test field and instance.
+ $field_name = 'test';
+ $field = array(
+ 'field_name' => $field_name,
+ 'type' => 'test_field'
+ );
+ field_create_field($field);
+ $instance = array(
+ 'field_name' => $field_name,
+ 'entity_type' => 'node',
+ 'bundle' => $this->type,
+ );
+ field_create_instance($instance);
+
+ $langcode = LANGUAGE_NONE;
+ $admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $field_name;
+ $element_id = "edit-$field_name-$langcode-0-value";
+ $element_name = "{$field_name}[$langcode][0][value]";
+ $this->drupalGet($admin_path);
+ $this->assertFieldById($element_id, '', 'The default value widget was empty.');
+
+ // Check that invalid default values are rejected.
+ $edit = array($element_name => '-1');
+ $this->drupalPost($admin_path, $edit, t('Save settings'));
+ $this->assertText("$field_name does not accept the value -1", 'Form vaildation failed.');
+
+ // Check that the default value is saved.
+ $edit = array($element_name => '1');
+ $this->drupalPost($admin_path, $edit, t('Save settings'));
+ $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
+ $instance = field_info_instance('node', $field_name, $this->type);
+ $this->assertEqual($instance['default_value'], array(array('value' => 1)), 'The default value was correctly saved.');
+
+ // Check that the default value shows up in the form
+ $this->drupalGet($admin_path);
+ $this->assertFieldById($element_id, '1', 'The default value widget was displayed with the correct value.');
+
+ // Check that the default value can be emptied.
+ $edit = array($element_name => '');
+ $this->drupalPost(NULL, $edit, t('Save settings'));
+ $this->assertText("Saved $field_name configuration", 'The form was successfully submitted.');
+ field_info_cache_clear();
+ $instance = field_info_instance('node', $field_name, $this->type);
+ $this->assertEqual($instance['default_value'], NULL, 'The default value was correctly saved.');
+ }
+
+ /**
+ * Tests that deletion removes fields and instances as expected.
+ */
+ function testDeleteField() {
+ // Create a new field.
+ $bundle_path1 = 'admin/structure/types/manage/' . $this->hyphen_type;
+ $edit1 = array(
+ 'fields[_add_new_field][label]' => $this->field_label,
+ 'fields[_add_new_field][field_name]' => $this->field_name_input,
+ );
+ $this->fieldUIAddNewField($bundle_path1, $edit1);
+
+ // Create an additional node type.
+ $type_name2 = strtolower($this->randomName(8)) . '_test';
+ $type2 = $this->drupalCreateContentType(array('name' => $type_name2, 'type' => $type_name2));
+ $type_name2 = $type2->type;
+ $hyphen_type2 = str_replace('_', '-', $type_name2);
+
+ // Add an instance to the second node type.
+ $bundle_path2 = 'admin/structure/types/manage/' . $hyphen_type2;
+ $edit2 = array(
+ 'fields[_add_existing_field][label]' => $this->field_label,
+ 'fields[_add_existing_field][field_name]' => $this->field_name,
+ );
+ $this->fieldUIAddExistingField($bundle_path2, $edit2);
+
+ // Delete the first instance.
+ $this->fieldUIDeleteField($bundle_path1, $this->field_name, $this->field_label, $this->type);
+
+ // Reset the fields info.
+ field_info_cache_clear();
+ // Check that the field instance was deleted.
+ $this->assertNull(field_info_instance('node', $this->field_name, $this->type), 'Field instance was deleted.');
+ // Check that the field was not deleted
+ $this->assertNotNull(field_info_field($this->field_name), 'Field was not deleted.');
+
+ // Delete the second instance.
+ $this->fieldUIDeleteField($bundle_path2, $this->field_name, $this->field_label, $type_name2);
+
+ // Reset the fields info.
+ field_info_cache_clear();
+ // Check that the field instance was deleted.
+ $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), 'Field instance was deleted.');
+ // Check that the field was deleted too.
+ $this->assertNull(field_info_field($this->field_name), 'Field was deleted.');
+ }
+
+ /**
+ * Tests that Field UI respects the 'no_ui' option in hook_field_info().
+ */
+ function testHiddenFields() {
+ $bundle_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/';
+
+ // Check that the field type is not available in the 'add new field' row.
+ $this->drupalGet($bundle_path);
+ $this->assertFalse($this->xpath('//select[@id="edit-add-new-field-type"]//option[@value="hidden_test_field"]'), "The 'add new field' select respects field types 'no_ui' property.");
+
+ // Create a field and an instance programmatically.
+ $field_name = 'hidden_test_field';
+ field_create_field(array('field_name' => $field_name, 'type' => $field_name));
+ $instance = array(
+ 'field_name' => $field_name,
+ 'bundle' => $this->type,
+ 'entity_type' => 'node',
+ 'label' => t('Hidden field'),
+ 'widget' => array('type' => 'test_field_widget'),
+ );
+ field_create_instance($instance);
+ $this->assertTrue(field_read_instance('node', $field_name, $this->type), format_string('An instance of the field %field was created programmatically.', array('%field' => $field_name)));
+
+ // Check that the newly added instance appears on the 'Manage Fields'
+ // screen.
+ $this->drupalGet($bundle_path);
+ $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $instance['label'], 'Field was created and appears in the overview page.');
+
+ // Check that the instance does not appear in the 'add existing field' row
+ // on other bundles.
+ $bundle_path = 'admin/structure/types/manage/article/fields/';
+ $this->drupalGet($bundle_path);
+ $this->assertFalse($this->xpath('//select[@id="edit-add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), "The 'add existing field' select respects field types 'no_ui' property.");
+ }
+
+ /**
+ * Tests renaming a bundle.
+ */
+ function testRenameBundle() {
+ $type2 = strtolower($this->randomName(8)) . '_' .'test';
+ $hyphen_type2 = str_replace('_', '-', $type2);
+
+ $options = array(
+ 'type' => $type2,
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type, $options, t('Save content type'));
+
+ $this->drupalGet('admin/structure/types/manage/' . $hyphen_type2 . '/fields');
+ }
+
+ /**
+ * Tests that a duplicate field name is caught by validation.
+ */
+ function testDuplicateFieldName() {
+ // field_tags already exists, so we're expecting an error when trying to
+ // create a new field with the same name.
+ $edit = array(
+ 'fields[_add_new_field][field_name]' => 'tags',
+ 'fields[_add_new_field][label]' => $this->randomName(),
+ 'fields[_add_new_field][type]' => 'taxonomy_term_reference',
+ 'fields[_add_new_field][widget_type]' => 'options_select',
+ );
+ $url = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields';
+ $this->drupalPost($url, $edit, t('Save'));
+
+ $this->assertText(t('The machine-readable name is already in use. It must be unique.'));
+ $this->assertUrl($url, array(), 'Stayed on the same page.');
+ }
+}
+
+/**
+ * Tests the functionality of the 'Manage display' screens.
+ */
+class FieldUIManageDisplayTestCase extends FieldUITestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Manage display',
+ 'description' => 'Test the Field UI "Manage display" screens.',
+ 'group' => 'Field UI',
+ );
+ }
+
+ function setUp() {
+ parent::setUp(array('search'));
+ }
+
+ /**
+ * Tests formatter settings.
+ */
+ function testFormatterUI() {
+ $manage_fields = 'admin/structure/types/manage/' . $this->hyphen_type;
+ $manage_display = $manage_fields . '/display';
+
+ // Create a field, and a node with some data for the field.
+ $edit = array(
+ 'fields[_add_new_field][label]' => 'Test field',
+ 'fields[_add_new_field][field_name]' => 'test',
+ );
+ $this->fieldUIAddNewField($manage_fields, $edit);
+
+ // Clear the test-side cache and get the saved field instance.
+ field_info_cache_clear();
+ $instance = field_info_instance('node', 'field_test', $this->type);
+ $format = $instance['display']['default']['type'];
+ $default_settings = field_info_formatter_settings($format);
+ $setting_name = key($default_settings);
+ $setting_value = $instance['display']['default']['settings'][$setting_name];
+
+ // Display the "Manage display" screen and check that the expected formatter is
+ // selected.
+ $this->drupalGet($manage_display);
+ $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.');
+ $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.');
+
+ // Change the formatter and check that the summary is updated.
+ $edit = array('fields[field_test][type]' => 'field_test_multiple', 'refresh_rows' => 'field_test');
+ $this->drupalPostAJAX(NULL, $edit, array('op' => t('Refresh')));
+ $format = 'field_test_multiple';
+ $default_settings = field_info_formatter_settings($format);
+ $setting_name = key($default_settings);
+ $setting_value = $default_settings[$setting_name];
+ $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.');
+ $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.');
+
+ // Submit the form and check that the instance is updated.
+ $this->drupalPost(NULL, array(), t('Save'));
+ field_info_cache_clear();
+ $instance = field_info_instance('node', 'field_test', $this->type);
+ $current_format = $instance['display']['default']['type'];
+ $current_setting_value = $instance['display']['default']['settings'][$setting_name];
+ $this->assertEqual($current_format, $format, 'The formatter was updated.');
+ $this->assertEqual($current_setting_value, $setting_value, 'The setting was updated.');
+ }
+
+ /**
+ * Tests switching view modes to use custom or 'default' settings'.
+ */
+ function testViewModeCustom() {
+ // Create a field, and a node with some data for the field.
+ $edit = array(
+ 'fields[_add_new_field][label]' => 'Test field',
+ 'fields[_add_new_field][field_name]' => 'test',
+ );
+ $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
+ // For this test, use a formatter setting value that is an integer unlikely
+ // to appear in a rendered node other than as part of the field being tested
+ // (for example, unlikely to be part of the "Submitted by ... on ..." line).
+ $value = 12345;
+ $settings = array(
+ 'type' => $this->type,
+ 'field_test' => array(LANGUAGE_NONE => array(array('value' => $value))),
+ );
+ $node = $this->drupalCreateNode($settings);
+
+ // Gather expected output values with the various formatters.
+ $formatters = field_info_formatter_types();
+ $output = array(
+ 'field_test_default' => $formatters['field_test_default']['settings']['test_formatter_setting'] . '|' . $value,
+ 'field_test_with_prepare_view' => $formatters['field_test_with_prepare_view']['settings']['test_formatter_setting_additional'] . '|' . $value. '|' . ($value + 1),
+ );
+
+ // Check that the field is displayed with the default formatter in 'rss'
+ // mode (uses 'default'), and hidden in 'teaser' mode (uses custom settings).
+ $this->assertNodeViewText($node, 'rss', $output['field_test_default'], "The field is displayed as expected in view modes that use 'default' settings.");
+ $this->assertNodeViewNoText($node, 'teaser', $value, "The field is hidden in view modes that use custom settings.");
+
+ // Change fomatter for 'default' mode, check that the field is displayed
+ // accordingly in 'rss' mode.
+ $edit = array(
+ 'fields[field_test][type]' => 'field_test_with_prepare_view',
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+ $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], "The field is displayed as expected in view modes that use 'default' settings.");
+
+ // Specialize the 'rss' mode, check that the field is displayed the same.
+ $edit = array(
+ "view_modes_custom[rss]" => TRUE,
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+ $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], "The field is displayed as expected in newly specialized 'rss' mode.");
+
+ // Set the field to 'hidden' in the view mode, check that the field is
+ // hidden.
+ $edit = array(
+ 'fields[field_test][type]' => 'hidden',
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display/rss', $edit, t('Save'));
+ $this->assertNodeViewNoText($node, 'rss', $value, "The field is hidden in 'rss' mode.");
+
+ // Set the view mode back to 'default', check that the field is displayed
+ // accordingly.
+ $edit = array(
+ "view_modes_custom[rss]" => FALSE,
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+ $this->assertNodeViewText($node, 'rss', $output['field_test_with_prepare_view'], "The field is displayed as expected when 'rss' mode is set back to 'default' settings.");
+
+ // Specialize the view mode again.
+ $edit = array(
+ "view_modes_custom[rss]" => TRUE,
+ );
+ $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/display', $edit, t('Save'));
+ // Check that the previous settings for the view mode have been kept.
+ $this->assertNodeViewNoText($node, 'rss', $value, "The previous settings are kept when 'rss' mode is specialized again.");
+ }
+
+ /**
+ * Asserts that a string is found in the rendered node in a view mode.
+ *
+ * @param $node
+ * The node.
+ * @param $view_mode
+ * The view mode in which the node should be displayed.
+ * @param $text
+ * Plain text to look for.
+ * @param $message
+ * Message to display.
+ *
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ function assertNodeViewText($node, $view_mode, $text, $message) {
+ return $this->assertNodeViewTextHelper($node, $view_mode, $text, $message, FALSE);
+ }
+
+ /**
+ * Asserts that a string is not found in the rendered node in a view mode.
+ *
+ * @param $node
+ * The node.
+ * @param $view_mode
+ * The view mode in which the node should be displayed.
+ * @param $text
+ * Plain text to look for.
+ * @param $message
+ * Message to display.
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ function assertNodeViewNoText($node, $view_mode, $text, $message) {
+ return $this->assertNodeViewTextHelper($node, $view_mode, $text, $message, TRUE);
+ }
+
+ /**
+ * Asserts that a string is (not) found in the rendered nodein a view mode.
+ *
+ * This helper function is used by assertNodeViewText() and
+ * assertNodeViewNoText().
+ *
+ * @param $node
+ * The node.
+ * @param $view_mode
+ * The view mode in which the node should be displayed.
+ * @param $text
+ * Plain text to look for.
+ * @param $message
+ * Message to display.
+ * @param $not_exists
+ * TRUE if this text should not exist, FALSE if it should.
+ *
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ function assertNodeViewTextHelper($node, $view_mode, $text, $message, $not_exists) {
+ // Make sure caches on the tester side are refreshed after changes
+ // submitted on the tested side.
+ field_info_cache_clear();
+
+ // Save current content so that we can restore it when we're done.
+ $old_content = $this->drupalGetContent();
+
+ // Render a cloned node, so that we do not alter the original.
+ $clone = clone $node;
+ $element = node_view($clone, $view_mode);
+ $output = drupal_render($element);
+ $this->verbose(t('Rendered node - view mode: @view_mode', array('@view_mode' => $view_mode)) . '<hr />'. $output);
+
+ // Assign content so that DrupalWebTestCase functions can be used.
+ $this->drupalSetContent($output);
+ $method = ($not_exists ? 'assertNoText' : 'assertText');
+ $return = $this->{$method}((string) $text, $message);
+
+ // Restore previous content.
+ $this->drupalSetContent($old_content);
+
+ return $return;
+ }
+}
+
+/**
+ * Tests custom widget hooks and callbacks on the field administration pages.
+ */
+class FieldUIAlterTestCase extends DrupalWebTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Widget customization',
+ 'description' => 'Test custom field widget hooks and callbacks on field administration pages.',
+ 'group' => 'Field UI',
+ );
+ }
+
+ function setUp() {
+ parent::setUp(array('field_test'));
+
+ // Create test user.
+ $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer users'));
+ $this->drupalLogin($admin_user);
+ }
+
+ /**
+ * Tests hook_field_widget_properties_alter() on the default field widget.
+ *
+ * @see field_test_field_widget_properties_alter()
+ * @see field_test_field_widget_properties_user_alter()
+ * @see field_test_field_widget_form_alter()
+ */
+ function testDefaultWidgetPropertiesAlter() {
+ // Create the alter_test_text field and an instance on article nodes.
+ field_create_field(array(
+ 'field_name' => 'alter_test_text',
+ 'type' => 'text',
+ ));
+ field_create_instance(array(
+ 'field_name' => 'alter_test_text',
+ 'entity_type' => 'node',
+ 'bundle' => 'article',
+ 'widget' => array(
+ 'type' => 'text_textfield',
+ 'size' => 60,
+ ),
+ ));
+
+ // Test that field_test_field_widget_properties_alter() sets the size to
+ // 42 and that field_test_field_widget_form_alter() reports the correct
+ // size when the form is displayed.
+ $this->drupalGet('admin/structure/types/manage/article/fields/alter_test_text');
+ $this->assertText('Field size: 42', 'Altered field size is found in hook_field_widget_form_alter().');
+
+ // Create the alter_test_options field.
+ field_create_field(array(
+ 'field_name' => 'alter_test_options',
+ 'type' => 'list_text'
+ ));
+ // Create instances on users and page nodes.
+ field_create_instance(array(
+ 'field_name' => 'alter_test_options',
+ 'entity_type' => 'user',
+ 'bundle' => 'user',
+ 'widget' => array(
+ 'type' => 'options_select',
+ )
+ ));
+ field_create_instance(array(
+ 'field_name' => 'alter_test_options',
+ 'entity_type' => 'node',
+ 'bundle' => 'page',
+ 'widget' => array(
+ 'type' => 'options_select',
+ )
+ ));
+
+ // Test that field_test_field_widget_properties_user_alter() replaces
+ // the widget and that field_test_field_widget_form_alter() reports the
+ // correct widget name when the form is displayed.
+ $this->drupalGet('admin/config/people/accounts/fields/alter_test_options');
+ $this->assertText('Widget type: options_buttons', 'Widget type is altered for users in hook_field_widget_form_alter().');
+
+ // Test that the widget is not altered on page nodes.
+ $this->drupalGet('admin/structure/types/manage/page/fields/alter_test_options');
+ $this->assertText('Widget type: options_select', 'Widget type is not altered for pages in hook_field_widget_form_alter().');
+ }
+}