You are here

public function TermMergeTermMergeWebTestCase::testTermMergeBatch in Term Merge 7

Test all cases of usage of Term Merge Batch.

File

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

Class

TermMergeTermMergeWebTestCase
Test the functionality of Term Merge module.

Code

public function testTermMergeBatch() {

  // Adding fields with unlimited cardinality to our vocabulary.
  $this
    ->drupalPost('admin/structure/taxonomy/vocabulary/fields', array(
    'fields[_add_new_field][label]' => 'Test Unlimited Text',
    'fields[_add_new_field][field_name]' => 'test_text',
    'fields[_add_new_field][type]' => 'text',
    'fields[_add_new_field][widget_type]' => 'text_textfield',
  ), 'Save');
  $this
    ->drupalPost(NULL, array(), 'Save field settings');
  $this
    ->drupalPost(NULL, array(
    'field[cardinality]' => FIELD_CARDINALITY_UNLIMITED,
  ), 'Save settings');

  // Additionally 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(), 'Save settings');

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

  // Array of cases for which we test the Term Merge batch.
  $cases = array(
    'taxonomy_vocabulary_tab',
    'taxonomy_term_tab',
    'via_term_trunk_widget_select',
    'via_term_trunk_widget_autocomplete',
    'via_term_trunk_widget_autocomplete_without_tid',
    'merge_fields',
    'do_not_merge_fields',
  );
  foreach ($cases as $case) {

    // Creating a necessary set of terms in the vocabulary.
    drupal_static_reset();
    $terms = array(
      'parent' => FALSE,
      'another_parent' => FALSE,
      'child' => FALSE,
      'term1' => FALSE,
      'term2' => FALSE,
      'term3' => FALSE,
      'term_trunk_parent' => FALSE,
      'term_trunk' => FALSE,
    );
    foreach ($terms as $term_type => $tmp) {
      $url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add';
      $edit = array(
        'name' => $term_type . '_' . $this
          ->randomName(),
        'field_test_text[' . LANGUAGE_NONE . '][0][value]' => $term_type,
      );
      switch ($term_type) {
        case 'child':
          $edit['parent[]'] = array(
            $terms['parent']->tid,
            $terms['another_parent']->tid,
          );
          break;
        case 'term_trunk':
          $edit['parent[]'] = array(
            $terms['term_trunk_parent']->tid,
          );
          break;
      }
      $this
        ->drupalPost($url, $edit, 'Save');
      $terms[$term_type] = $this
        ->getLastTerm($this->vocabulary);
    }

    // The initial URL from where the form that kicks off batch is submitted.
    $init_url = '';

    // What widget to use for choosing term trunk.
    $term_trunk_widget = '';

    // Value for term trunk in the format, expected by the widget
    // $term_trunk_widget. Additionally, if any test case requires any extra
    // fields to be submitted, input those fields into this array and they
    // won't be taken out from this array, then it will get merged into $edit,
    // and this way eventually your values will be successfully submitted.
    $term_trunk_edit = array();

    // Setting up controlling vars based on case and doing any specific
    // assertions for each case.
    switch ($case) {
      case 'taxonomy_vocabulary_tab':
        $init_url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/merge';

        // It doesn't really matter which widget we use, we test widgets
        // throughout in other cases.
        $term_trunk_widget = array_rand(drupal_map_assoc(array(
          'select',
          'autocomplete',
        )));
        break;
      case 'taxonomy_term_tab':
        $init_url = 'taxonomy/term/' . $terms['parent']->tid . '/merge';

        // It doesn't really matter which widget we use, we test widgets
        // throughout in other cases.
        $term_trunk_widget = array_rand(drupal_map_assoc(array(
          'select',
          'autocomplete',
        )));

        // Assert that the term, for which the tab was clicked, is selected as
        // term branch by default.
        $this
          ->drupalGet($init_url);
        $this
          ->assertOptionSelected('edit-term-branch', $terms['parent']->tid, 'Clicking the "Merge Terms" tab from a term view page sets the viewed term as a term branch by default.');
        break;
      case 'via_term_trunk_widget_select':
        $init_url = 'taxonomy/term/' . $terms['parent']->tid . '/merge';
        $term_trunk_widget = 'select';

        // Making sure for the term trunk select the selected term branch are
        // not available, nor their children.
        $this
          ->drupalGet($init_url);
        $matches = array();
        preg_match('#\\<select[^>]+name="term_trunk\\[tid\\]"[^>]*\\>.+?\\</select\\>#si', $this->content, $matches);
        $term_trunk_options = $matches[0];
        $str_pos = strpos($term_trunk_options, $terms['child']->name);
        $this
          ->assertIdentical(FALSE, $str_pos, 'Child is not available as option for term trunk if its parent is chosen among term branches.');
        $str_pos = strpos($term_trunk_options, $terms['parent']->name);
        $this
          ->assertIdentical(FALSE, $str_pos, 'Selected branch term is not available as an option for term trunk.');
        break;
      case 'via_term_trunk_widget_autocomplete':
        $init_url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/merge';
        $term_trunk_widget = 'autocomplete';

        // Test autocomplete widget menu path to make sure it does reply
        // with valid suggestions.
        $response = $this
          ->drupalGet('term-merge/autocomplete/term-trunk/' . $this->vocabulary->machine_name . '/' . drupal_strtoupper($terms['term_trunk']->name));
        $response = drupal_json_decode($response);
        $autocomplete_key = $terms['term_trunk']->name . ' (' . $terms['term_trunk']->tid . ')';
        $this
          ->assertTrue(isset($response[$autocomplete_key]), 'Autocomplete menu path replies with valid suggestions for term trunk autocomplete widget.');

        // Making sure for the term trunk autocomplete widget doesn't allow to
        // submit any of the selected term branches nor their children.
        $prohibited_terms = array(
          'parent' => 'Merging into the same term is not allowed in autocomplete widget for term trunk.',
          'child' => 'Merging into any of child of selected branch terms is not allowed in autocomplete widget for term trunk.',
        );
        foreach ($prohibited_terms as $term => $assert_message) {
          $term = $terms[$term];
          $this
            ->drupalGet($init_url);
          $this
            ->drupalPostAJAX(NULL, array(
            'term_branch[]' => array(
              $terms['parent']->tid,
            ),
            'term_trunk[widget]' => $term_trunk_widget,
          ), 'term_trunk[widget]');
          $this
            ->drupalPost(NULL, array(
            'term_branch[]' => array(
              $terms['parent']->tid,
            ),
            'term_trunk[widget]' => $term_trunk_widget,
            'term_trunk[tid]' => $term->name . ' (' . $term->tid . ')',
          ), 'Submit');
          $this
            ->assertText('Trunk term cannot be one of the selected branch terms or their children', $assert_message);
        }
        break;
      case 'via_term_trunk_widget_autocomplete_without_tid':
        $init_url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/merge';
        $term_trunk_widget = 'autocomplete';

        // Making sure for the term trunk autocomplete widget doesn't allow to
        // submit any of the selected term branches nor their children.
        $prohibited_terms = array(
          'parent' => 'Merging into the same term is not allowed in autocomplete widget for term trunk.',
          'child' => 'Merging into any of child of selected branch terms is not allowed in autocomplete widget for term trunk.',
        );
        foreach ($prohibited_terms as $term => $assert_message) {
          $term = $terms[$term];
          $this
            ->drupalGet($init_url);
          $this
            ->drupalPostAJAX(NULL, array(
            'term_branch[]' => array(
              $terms['parent']->tid,
            ),
            'term_trunk[widget]' => $term_trunk_widget,
          ), 'term_trunk[widget]');
          $this
            ->drupalPost(NULL, array(
            'term_branch[]' => array(
              $terms['parent']->tid,
            ),
            'term_trunk[widget]' => $term_trunk_widget,
            'term_trunk[tid]' => $term->name,
          ), 'Submit');
          $this
            ->assertText('Trunk term cannot be one of the selected branch terms or their children', $assert_message);
        }
        break;
      case 'merge_fields':
        $init_url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/merge';

        // It doesn't really matter which widget we use, we test widgets
        // throughout in other cases.
        $term_trunk_widget = array_rand(drupal_map_assoc(array(
          'select',
          'autocomplete',
        )));

        // We embed extra info related to field values merging into
        // $term_trunk_edit.
        $term_trunk_edit['merge_fields[field_test_text]'] = TRUE;
        break;
      case 'do_not_merge_fields':
        $init_url = 'admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/merge';

        // It doesn't really matter which widget we use, we test widgets
        // throughout in other cases.
        $term_trunk_widget = array_rand(drupal_map_assoc(array(
          'select',
          'autocomplete',
        )));
        break;
    }

    // Creating a new node and setting 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['term1']->name,
    ), 'Save');
    $node = $this
      ->drupalGetNodeByTitle($title, TRUE);

    // Calling the Term Merge form.
    $this
      ->drupalGet($init_url);

    // Choosing term branches.
    $term_branches = array(
      'term1',
      'term2',
      'term3',
    );
    $term_branches_edit = array();
    foreach ($term_branches as $term_type) {
      $term_branches_edit[] = $terms[$term_type]->tid;
    }
    $this
      ->drupalPostAJAX(NULL, array(
      'term_branch[]' => $term_branches_edit,
    ), 'term_branch[]');

    // Choosing the widget for trunk term.
    $this
      ->drupalPostAJAX(NULL, array(
      'term_branch[]' => $term_branches_edit,
      'term_trunk[widget]' => $term_trunk_widget,
    ), 'term_trunk[widget]');

    // Choosing term trunk.
    switch ($term_trunk_widget) {
      case 'select':
        $term_trunk_edit += array(
          'term_trunk[tid]' => $terms['term_trunk']->tid,
        );
        break;
      case 'autocomplete':
        $term_trunk_edit += array(
          'term_trunk[tid]' => $terms['term_trunk']->name . ' (' . $terms['term_trunk']->tid . ')',
        );
        break;
    }

    // Submitting the form.
    $edit = $term_trunk_edit + array(
      'term_branch[]' => $term_branches_edit,
      'term_trunk[widget]' => $term_trunk_widget,
      'term_branch_keep' => FALSE,
      'step' => 2,
    );
    $this
      ->drupalPost(NULL, $edit, 'Submit');
    $this
      ->drupalPost(NULL, array(), 'Confirm');

    // Making sure all the branches are deleted.
    foreach ($term_branches as $term_type) {
      $term = $terms[$term_type];
      $this
        ->drupalGet('taxonomy/term/' . $term->tid);
      $this
        ->assertResponse(404, 'Branch term ' . $term_type . ' has been deleted after merging.');
    }
    $text_assertions = array();
    $term_trunk = $terms['term_trunk'];

    // Adding any extra text assertions on per test-case basis.
    switch ($case) {
      case 'merge_fields':

        // Making sure the term trunk has been merged all the fields from term
        // branches into itself.
        foreach ($term_branches as $term_type) {
          $items = field_get_items('taxonomy_term', $terms[$term_type], 'field_test_text');
          foreach ($items as $delta => $item) {
            $text_assertions[$term_type . ' text field delta#' . $delta . ' has been merged when instructed to merge field values.'] = $item['value'];
          }
        }
        break;
      case 'do_not_merge_fields':

        // We need to assert that no values for field have been merged from
        // branch terms into the values of trunk term.
        $this
          ->drupalGet('taxonomy/term/' . $term_trunk->tid);
        foreach ($term_branches as $term_type) {
          $items = field_get_items('taxonomy_term', $terms[$term_type], 'field_test_text');
          foreach ($items as $delta => $item) {
            $this
              ->assertNoText($item['value'], $term_type . ' text field delta#' . $delta . ' has not been merged when instrcuted not to merge field values.');
          }
        }
        break;
    }
    $this
      ->drupalGet('taxonomy/term/' . $term_trunk->tid);
    foreach ($text_assertions as $k => $v) {
      $this
        ->assertText($v, 'Term trunk has the property ' . $k);
    }

    // Making sure the taxonomy term reference in other entities are updated
    // to point from term branches to the just created term trunk.
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertText($term_trunk->name, 'Taxonomy term reference fields in other entities are updated to point from term branches to the term trunk.');
  }
}