You are here

public function TermMergeTermMergeWebTestCase::testTermMerge in Term Merge 7

Test merging two terms.

File

./term_merge.test, line 121
Test the Term Merge module.

Class

TermMergeTermMergeWebTestCase
Test the functionality of Term Merge module.

Code

public function testTermMerge() {

  // Checking whether parent's relationship is handled as it should.
  // At the same time we make sure 'term_branch_keep' property functions.
  $terms = array(
    'trunk' => FALSE,
    'branch' => FALSE,
    'another_parent' => FALSE,
    'branch_child' => FALSE,
  );
  foreach ($terms as $term_type => $tmp) {
    $url = 'admin/structure/taxonomy/vocabulary/add';
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
    );

    // Putting "branch" to be parent of "branch_child".
    if ($term_type == 'branch_child') {
      $edit['parent[]'] = array(
        $terms['branch']->tid,
        $terms['another_parent']->tid,
      );
    }
    $this
      ->drupalPost($url, $edit, 'Save');
    $terms[$term_type] = $this
      ->getLastTerm($this->vocabulary);
  }

  // Firstly we try to merge without deleting the branch term and make sure
  // branch's children are not reassigned to the trunk term nor the branch
  // term itself is deleted.
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => TRUE,
  ));
  $this
    ->drupalGet('taxonomy/term/' . $terms['branch']->tid);
  $this
    ->assertText($terms['branch']->name);
  drupal_static_reset();
  $parents = array();
  foreach (taxonomy_get_parents_all($terms['branch_child']->tid) as $parent) {
    $parents[] = $parent->tid;
  }
  $valid_parents = array(
    $terms['branch_child']->tid,
    $terms['branch']->tid,
    $terms['another_parent']->tid,
  );
  $intersection = array_intersect($parents, $valid_parents);
  $this
    ->assertTrue(count($intersection) == count($valid_parents), 'The parents of children of term branch are not updated if property "term_branch_keep" is set to FALSE.');

  // Now we merge with deletion of branch term, thus the parents of its
  // children have to be updated.
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => FALSE,
  ));
  $this
    ->drupalGet('taxonomy/term/' . $terms['branch']->tid);
  $this
    ->assertResponse(404, 'The branch term has been deleted.');
  drupal_static_reset();
  $parents = array();
  foreach (taxonomy_get_parents_all($terms['branch_child']->tid) as $parent) {
    $parents[] = $parent->tid;
  }
  $valid_parents = array(
    $terms['branch_child']->tid,
    $terms['trunk']->tid,
    $terms['another_parent']->tid,
  );
  $intersection = array_intersect($parents, $valid_parents);
  $this
    ->assertTrue(count($intersection) == count($valid_parents), 'The parents of children of term branch are updated if property "term_branch_keep" is set to TRUE.');

  // Now testing 'merge_fields' property. Attaching fields to taxonomy terms.
  $bundle = field_extract_bundle('taxonomy_term', $this->vocabulary);
  $fields_map = array(
    'term_merge_test_single' => 1,
    'term_merge_test_unlimited' => FIELD_CARDINALITY_UNLIMITED,
    'term_merge_do_not_merge' => 10,
    'term_merge_not_unique' => FIELD_CARDINALITY_UNLIMITED,
  );
  foreach ($fields_map as $field_name => $cardinality) {
    $field = array(
      'field_name' => $field_name,
      'cardinality' => $cardinality,
      'locked' => TRUE,
      'type' => 'text',
    );
    field_create_field($field);
    field_create_instance(array(
      'field_name' => $field_name,
      'entity_type' => 'taxonomy_term',
      'bundle' => $bundle,
      'label' => $field_name,
    ));
  }
  $terms = array(
    'trunk' => FALSE,
    'branch' => FALSE,
  );
  foreach ($terms as $term_type => $tmp) {
    $term = (object) array(
      'vid' => $this->vocabulary->vid,
      'name' => $this
        ->randomName(),
    );
    foreach ($fields_map as $field_name => $cardinality) {
      switch ($field_name) {
        case 'term_merge_test_single':
          $term->{$field_name}[LANGUAGE_NONE][0]['value'] = $this
            ->randomName();
          break;
        case 'term_merge_test_unlimited':
        case 'term_merge_do_not_merge':
          $count = rand(1, 3);
          for ($i = 0; $i < $count; $i++) {
            $term->{$field_name}[LANGUAGE_NONE][$i]['value'] = $this
              ->randomName();
          }
          break;
        case 'term_merge_not_unique':
          $term->{$field_name}[LANGUAGE_NONE][0]['value'] = 'term_merge_not_unique_value';
          break;
      }
    }
    taxonomy_term_save($term);
    $terms[$term_type] = $this
      ->getLastTerm($this->vocabulary);
  }

  // Firstly we make sure if 'merge_fields' is disabled, the fields are not
  // merged.
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => TRUE,
  ));
  $this
    ->drupalGet('taxonomy/term/' . $terms['trunk']->tid);
  foreach ($fields_map as $field_name => $cardinality) {
    foreach (field_get_items('taxonomy_term', $terms['branch'], $field_name) as $item) {
      if ($field_name != 'term_merge_not_unique') {
        $this
          ->assertNoText($item['value'], 'Values of field ' . $field_name . ' have not been added to the trunk term with disabled "merge_fields" option.');
      }
    }
  }

  // Now we try merging with merging fields. The values of the branch term
  // should be added to the trunk term's values only in where we asked them
  // to be added. Moreover, only unique values are to be kept in each of the
  // merged fields.
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(
      'term_merge_test_single',
      'term_merge_test_unlimited',
      'term_merge_not_unique',
    ),
    'term_branch_keep' => TRUE,
  ));
  $this
    ->drupalGet('taxonomy/term/' . $terms['trunk']->tid);
  foreach ($fields_map as $field_name => $cardinality) {
    switch ($field_name) {
      case 'term_merge_test_single':
      case 'term_merge_do_not_merge':

        // Make sure if cardinality limit is hit, firstly original trunk term
        // values are stored. And make sure values of fields that are not
        // instructed to be added to trunk term's values are actually not
        // added.
        foreach (field_get_items('taxonomy_term', $terms['branch'], $field_name) as $item) {
          $this
            ->assertNoText($item['value'], 'Values of field ' . $field_name . ' (cardinality ' . $cardinality . ') have not been added to the trunk term with enabled "merge_fields" option.');
        }
        break;
      case 'term_merge_not_unique':

        // Make sure only the unique values in merged field are kept.
        foreach (field_get_items('taxonomy_term', $terms['trunk'], $field_name) as $item) {
          $this
            ->assertUniqueText($item['value'], 'Only unique field values are kept in the trunk term field after merging terms with enabled "merge_fields" option.');
        }
        break;
      case 'term_merge_test_unlimited':

        // Make sure values of fields that are instructed to be added to trunk
        // term's values are actually added.
        foreach (field_get_items('taxonomy_term', $terms['branch'], $field_name) as $item) {
          $this
            ->assertText($item['value'], 'Values of field ' . $field_name . ' (cardinality ' . $cardinality . ') have been added to the trunk term with enabled "merge_fields" option.');
        }
        break;
    }
  }

  // Make sure that all taxonomy term reference fields are updated to point
  // from a branch term to a trunk term in other entities that have taxonomy
  // term reference fields.
  $terms = array(
    'trunk' => FALSE,
    'branch' => FALSE,
  );
  foreach ($terms as $term_type => $tmp) {
    $url = 'admin/structure/taxonomy/vocabulary/add';
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
    );
    $this
      ->drupalPost($url, $edit, 'Save');
    $terms[$term_type] = $this
      ->getLastTerm($this->vocabulary);
  }

  // Firstly we need to create a new content type and assign term reference
  // field to this new content type.
  $this
    ->drupalPost('admin/structure/types/add', array(
    'name' => $this
      ->randomName(),
    'type' => 'term_merge_node',
  ), 'Save content type');
  $this
    ->drupalPost('admin/structure/types/manage/term-merge-node/fields', array(
    'fields[_add_new_field][label]' => 'Term Reference',
    'fields[_add_new_field][field_name]' => 'term_reference',
    'fields[_add_new_field][type]' => 'taxonomy_term_reference',
    'fields[_add_new_field][widget_type]' => 'taxonomy_autocomplete',
  ), 'Save');
  $this
    ->drupalPost(NULL, array(
    'field[settings][allowed_values][0][vocabulary]' => $this->vocabulary->machine_name,
  ), 'Save field settings');
  $this
    ->drupalPost(NULL, array(
    'field[cardinality]' => FIELD_CARDINALITY_UNLIMITED,
  ), 'Save settings');

  // Flushing fields API cache.
  _field_info_collate_fields(TRUE);

  // Creating a new node and settings its term reference field to point to
  // the term branch.
  $title = $this
    ->randomName();
  $this
    ->drupalPost('node/add/term-merge-node', array(
    'title' => $title,
    'field_term_reference[' . LANGUAGE_NONE . ']' => $terms['branch']->name,
  ), 'Save');
  $node = $this
    ->drupalGetNodeByTitle($title, TRUE);
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => TRUE,
  ));
  $this
    ->drupalGet('node/' . $node->nid);
  $this
    ->assertText($terms['trunk']->name, 'Taxonomy term reference field gets updated to point from term branch to term trunk after merging terms.');

  // Testing 'Keep only unique' setting for merging. We create a node assigned
  // to both branch and trunk terms, and merge with, and then without 'Keep
  // only unique' setting, asserting each result.
  $terms = array(
    'trunk' => FALSE,
    'branch' => FALSE,
  );
  foreach ($terms as $term_type => $tmp) {
    $url = 'admin/structure/taxonomy/vocabulary/add';
    $name = $this
      ->randomName();
    $edit = array(
      'name' => $name,
    );
    $this
      ->drupalPost($url, $edit, 'Save');
    $terms[$term_type] = $this
      ->getLastTerm($this->vocabulary);
  }
  $title = $this
    ->randomName();
  $this
    ->drupalPost('node/add/term-merge-node', array(
    'title' => $title,
    'field_term_reference[' . LANGUAGE_NONE . ']' => $terms['branch']->name . ', ' . $terms['trunk']->name,
  ), 'Save');
  actions_do('term_merge_action', $terms['branch'], array(
    'term_trunk' => $terms['trunk']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => TRUE,
    'keep_only_unique' => FALSE,
  ));
  $node = $this
    ->drupalGetNodeByTitle($title);
  $is_first_trunk = $node->field_term_reference[LANGUAGE_NONE][0]['tid'] == $terms['trunk']->tid;
  $is_second_trunk = $node->field_term_reference[LANGUAGE_NONE][1]['tid'] == $terms['trunk']->tid;
  $this
    ->assertTrue($is_first_trunk && $is_second_trunk, 'The same terms are kept in term reference field values if "Keep only unique" is off.');

  // We switch roles of 'trunk' and 'branch' now. We have a node with 2 terms,
  // if we merge them into another with "Keep only unique" on we are supposed
  // to have only 1 term after merging.
  actions_do('term_merge_action', $terms['trunk'], array(
    'term_trunk' => $terms['branch']->tid,
    'merge_fields' => array(),
    'term_branch_keep' => TRUE,
    'keep_only_unique' => TRUE,
  ));
  $node = $this
    ->drupalGetNodeByTitle($title, TRUE);
  $is_single = count($node->field_term_reference[LANGUAGE_NONE]) == 1;
  $is_expected_term = $node->field_term_reference[LANGUAGE_NONE][0]['tid'] == $terms['branch']->tid;
  $this
    ->assertTrue($is_single && $is_expected_term, 'Only one term is kept in term reference field values if "Keep only unique" is on.');
}