You are here

conditional_fields.test in Conditional Fields 7.3

Test Conditional Fields functionality and UI.

File

tests/conditional_fields.test
View source
<?php

/**
 * @file
 * Test Conditional Fields functionality and UI.
 */
class ConditionalFieldsTestCase extends DrupalWebTestCase {
  protected $dependee_on_value;
  protected $dependee_off_value;
  protected $dependents;
  public static function getInfo() {
    return array(
      'name' => 'Conditional Fields',
      'description' => 'Test Conditional Fields functionality.',
      'group' => 'Conditional Fields',
    );
  }
  public function setUp() {

    // Load all core modules that define field types.
    parent::setUp('conditional_fields_test', 'list', 'text', 'number', 'taxonomy', 'image');

    // Create and log in user.
    $web_user = $this
      ->drupalCreateUser(array(
      'create conditional_fields_test content',
      'edit any conditional_fields_test content',
    ));
    $this
      ->drupalLogin($web_user);

    // Create a vocabulary and two terms to test the term reference field.
    $vocabulary = new stdClass();
    $vocabulary->name = $this
      ->randomName();
    $vocabulary->machine_name = drupal_strtolower($this
      ->randomName());
    taxonomy_vocabulary_save($vocabulary);
    $term = new stdClass();
    $term->name = 'Foo';
    $term->vid = $vocabulary->vid;
    taxonomy_term_save($term);
    $term = new stdClass();
    $term->name = 'Bar';
    $term->vid = $vocabulary->vid;
    taxonomy_term_save($term);

    // Create dependee.
    $this->dependee_on_value = $this
      ->randomString();
    $this->dependee_off_value = $this
      ->randomString();
    $dependee = array(
      'field_name' => 'dependee',
      'type' => 'list_text',
      'settings' => array(
        'allowed_values' => array(
          $this->dependee_on_value => t('Dependent fields are visible'),
          $this->dependee_off_value => t('Dependent fields are invisible'),
        ),
      ),
    );
    field_create_field($dependee);
    $dependee_instance = array(
      'field_name' => 'dependee',
      'entity_type' => 'node',
      'bundle' => 'conditional_fields_test',
      'label' => 'dependee_label',
    );
    field_create_instance($dependee_instance);

    // Reload the instance because we need the instance id.
    $dependee_instance = field_info_instance('node', 'dependee', 'conditional_fields_test');

    // Prepare one field for each widget type/field type combination.
    foreach (field_info_widget_types() as $widget_type => $widget_info) {

      // TODO: test files and images.
      if ($widget_type == 'file_generic' || $widget_type == 'image_image') {
        continue;
      }
      foreach ($widget_info['field types'] as $field_type) {
        $field_name = 'dependent_' . drupal_strtolower($this
          ->randomName());
        $dependent = array(
          'field_name' => $field_name,
          'type' => $field_type,
          'cardinality' => 1,
        );

        // Some fields need allowed values to function properly.
        if ($widget_info['module'] == 'options') {
          $dependent['settings']['allowed_values'] = array(
            'Foo',
            'Bar',
          );
        }
        if ($field_type == 'taxonomy_term_reference') {
          $dependent['settings']['allowed_values'] = array(
            array(
              'vocabulary' => $vocabulary->machine_name,
              'parent' => '0',
            ),
          );
        }
        $dependent_instance = array(
          'field_name' => $field_name,
          'entity_type' => 'node',
          'bundle' => 'conditional_fields_test',
          'widget' => array(
            'type' => $widget_type,
            'settings' => array(
              'display_label' => 1,
            ),
          ),
          'required' => TRUE,
          'label' => $widget_type . '_' . $field_type . '_label',
        );

        // Radios spit an error if submitted with no value.
        if ($widget_type == 'options_buttons' && $widget_info['module'] == 'list') {

          // This is the "Bar" option.
          $dependent_instance['default_value'] = 1;
        }
        $this->dependents[] = array(
          'field_type' => $field_type,
          'widget_type' => $widget_type,
          'widget' => $widget_info,
          'field' => $dependent,
          'instance' => $dependent_instance,
        );

        // Create a multiple value version of most fields.
        if ($widget_type == 'options_onoff') {
          continue;
        }
        $dependent['cardinality'] = -1;
        $dependent['field_name'] = $dependent_instance['field_name'] = $field_name . '_multiple';
        $dependent_instance['label'] .= '_multiple';
        $this->dependents[] = array(
          'field_type' => $field_type,
          'widget_type' => $widget_type,
          'widget' => $widget_info,
          'field' => $dependent,
          'instance' => $dependent_instance,
        );
      }
    }

    // Create fields and dependencies.
    $dependency_options = array(
      'value_form' => $this->dependee_on_value,
      'value' => array(
        array(
          'value' => $this->dependee_on_value,
        ),
      ),
    );
    foreach ($this->dependents as $dependent) {
      field_create_field($dependent['field']);
      field_create_instance($dependent['instance']);
      $dependent_instance = field_info_instance('node', $dependent['field']['field_name'], 'conditional_fields_test');
      conditional_fields_dependency_insert($dependee_instance['id'], $dependent_instance['id'], $dependency_options);
    }
  }

  /**
   * Tests field dependencies on a node.
   */
  public function testNodeDependencies() {

    // Try to submit a node with triggered dependencies.
    // The submit should fail because the dependent fields are required.
    $langcode = LANGUAGE_NONE;
    $edit = array(
      "dependee[{$langcode}]" => $this->dependee_on_value,
    );
    $this
      ->drupalPost('node/add/conditional-fields-test', $edit, t('Save'));
    foreach ($this->dependents as $dependent) {

      // Skip fields that always have a default value.
      if ($dependent['widget_type'] == 'options_buttons' && $dependent['field']['cardinality'] == 1 || in_array($dependent['widget_type'], array(
        'options_select',
        'options_buttons',
      )) && $dependent['field_type'] == 'taxonomy_term_reference') {
        continue;
      }

      // Multiple value textfields are dumb and can't find their own name.
      if ($dependent['field']['cardinality'] == -1 && in_array($dependent['widget_type'], array(
        'number',
        'text_textfield',
        'text_textarea',
        'text_textarea_with_summary',
      ))) {
        $name = '';
      }
      else {
        $name = $dependent['widget_type'] . '_' . $dependent['field_type'] . '_label';
        $name .= $dependent['field']['cardinality'] == -1 ? '_multiple' : '';
      }
      $this
        ->assertRaw(t('!name field is required.', array(
        '!name' => $name,
      )), 'Triggered ' . ($dependent['field']['cardinality'] == -1 ? 'multiple' : 'single') . ' value required ' . $dependent['field_type'] . ' dependent with widget ' . $dependent['widget_type'] . ' and no value fails validation');
    }

    // Fill the dependents with values and save the node.
    $edit = array(
      "dependee[{$langcode}]" => $this->dependee_on_value,
    );
    foreach ($this->dependents as $dependent) {

      // Text fields have structure field_name[langcode][delta][value].
      if (in_array($dependent['widget_type'], array(
        'number',
        'text_textfield',
        'text_textarea',
        'text_textarea_with_summary',
      ))) {
        $edit[$dependent['field']['field_name'] . "[{$langcode}][0][value]"] = '1';
      }
      elseif ($dependent['widget_type'] == 'options_select') {
        if ($dependent['field']['cardinality'] == 1) {

          // Single value select fields have structure field_name[langcode].
          $edit[$dependent['field']['field_name'] . "[{$langcode}]"] = '1';
        }
        else {

          // Multiple value select fields have structure field_name[langcode][].
          $edit[$dependent['field']['field_name'] . "[{$langcode}][]"] = '1';
        }
      }
      elseif (in_array($dependent['widget_type'], array(
        'options_buttons',
        'options_onoff',
        'taxonomy_autocomplete',
      ))) {
        if ($dependent['field']['cardinality'] == 1 || $dependent['widget_type'] == 'taxonomy_autocomplete') {

          // Radios and autocomplete fields have structure field_name[langcode].
          $edit[$dependent['field']['field_name'] . "[{$langcode}]"] = '1';
        }
        else {

          // Checkboxes have structure field_name[langcode][delta].
          $edit[$dependent['field']['field_name'] . "[{$langcode}][1]"] = '1';
        }
      }
      elseif (in_array($dependent['widget_type'], array(
        'file_generic',
        'image_image',
      ))) {

        // TODO.
        // $edit[$dependent['field']['field_name'] . "[$langcode][0][fid]"] = '1';
      }
    }
    $this
      ->drupalPost('node/add/conditional-fields-test', $edit, t('Save'));
    $this
      ->assertRaw(t('@type %title has been created.', array(
      '@type' => 'Conditional Fields Test Node Type',
      '%title' => '',
    )), 'Node was created with triggered dependencies.');

    // Verify that the fields are visible on node view.
    foreach ($this->dependents as $dependent) {
      $this
        ->assertText($dependent['instance']['label'] . ':', 'Triggered ' . ($dependent['field']['cardinality'] == -1 ? 'multiple' : 'single') . ' value ' . $dependent['field_type'] . ' dependent with widget ' . $dependent['widget_type'] . ' is visible on node view');
    }

    // Untrigger the dependency and verify that node is updated.
    $edit = array(
      "dependee[{$langcode}]" => $this->dependee_off_value,
    );
    $this
      ->drupalPost('node/1/edit', $edit, t('Save'));
    $this
      ->assertRaw(t('@type %title has been updated.', array(
      '@type' => 'Conditional Fields Test Node Type',
      '%title' => '',
    )), 'Node was updated with untriggered dependencies.');

    // Verify that fields are invisible on node view.
    foreach ($this->dependents as $dependent) {
      $this
        ->assertNoText($dependent['instance']['label'] . ':', 'Triggered ' . ($dependent['field']['cardinality'] == -1 ? 'multiple' : 'single') . ' value ' . $dependent['field_type'] . ' dependent with widget ' . $dependent['widget_type'] . ' is invisible on node view');
    }
  }

}
class ConditionalFieldsUITestCase extends DrupalWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'Conditional Fields UI',
      'description' => 'Test Conditional Fields UI.',
      'group' => 'Conditional Fields',
    );
  }
  public function setUp() {
    parent::setUp('conditional_fields_test', 'list', 'text');

    // Create and log in user.
    $web_user = $this
      ->drupalCreateUser(array(
      'access administration pages',
      'administer content types',
      'administer dependencies',
    ));
    $this
      ->drupalLogin($web_user);

    // Create a field that will be used as a dependee.
    $dependee = array(
      'field_name' => 'dependee',
      'type' => 'list_text',
      'settings' => array(
        'allowed_values' => array(
          'on' => t('Dependent is visible'),
          'off' => t('Dependent is invisible'),
        ),
      ),
    );
    field_create_field($dependee);
    $instance = array(
      'field_name' => 'dependee',
      'entity_type' => 'node',
      'bundle' => 'conditional_fields_test',
      'label' => t('Label of the dependee field'),
    );
    field_create_instance($instance);

    // Create a field that will be used as a dependent.
    $dependent = array(
      'field_name' => 'dependent',
      'type' => 'text',
    );
    field_create_field($dependent);
    $instance = array(
      'field_name' => 'dependent',
      'entity_type' => 'node',
      'bundle' => 'conditional_fields_test',
      'label' => t('Label of the dependent field'),
    );
    field_create_instance($instance);
  }

  /**
   * Ensures that the administration pages are viewable.
   */
  public function testDependenciesOverview() {
    $dependee = field_read_instance('node', 'dependee', 'conditional_fields_test');
    $this
      ->drupalGet('admin/structure');
    $this
      ->clickLink(t('Field dependencies'));
    $this
      ->clickLink(t('Node'));
    $this
      ->drupalGet('admin/structure/types/manage/conditional-fields-test');
    $this
      ->clickLink(t('Manage dependencies'));
    $this
      ->assertFieldByName('dependee', $dependee['id'], 'The dependee selection field is in the content type dependencies page.');
    $this
      ->assertFieldByName('dependent', $dependee['id'], 'The dependent selection field is in the content type dependencies page.');
  }

  /**
   * Tests adding, editing and deleting a dependency.
   */
  public function testDependencyOperations() {

    // Add dependency.
    $dependee = field_read_instance('node', 'dependee', 'conditional_fields_test');
    $dependent = field_read_instance('node', 'dependent', 'conditional_fields_test');
    $edit = array(
      'dependee' => $dependee['id'],
      'dependent' => $dependent['id'],
    );
    $this
      ->drupalPost('admin/structure/types/manage/conditional-fields-test/dependencies', $edit, t('Add dependency'), array(), array(), 'conditional-fields-dependency-add-form-node-conditional-fields-test');

    // Edit dependency.
    $edit = array(
      'values_set' => CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND,
      'values' => 'on',
    );
    $this
      ->drupalPost(NULL, $edit, t('Save settings'), array(
      'query' => array(
        'destination' => 'admin/structure/types/manage/conditional-fields-test/dependencies',
      ),
    ));
    $this
      ->assertRaw(t('%dependent_name is !state when %dependee_name has all the values: @values.', array(
      '%dependent_name' => t('Label of the dependent field'),
      '!state' => 'visible',
      '%dependee_name' => t('Label of the dependee field'),
      '@values' => 'on',
    )), 'The dependency was updated correctly.');

    // Delete dependency.
    $this
      ->clickLink(t('delete'));
    $this
      ->drupalPost(NULL, array(), t('Delete dependency'), array(
      'query' => array(
        'destination' => 'admin/structure/types/manage/conditional-fields-test/dependencies',
      ),
    ));
    $this
      ->assertText(t('The dependency has been deleted.'));
  }

}

Classes

Namesort descending Description
ConditionalFieldsTestCase @file Test Conditional Fields functionality and UI.
ConditionalFieldsUITestCase