public function UpgradePathTaxonomyTestCase::testTaxonomyUpgrade

Basic tests for the taxonomy upgrade.

File

drupal/modules/simpletest/tests/upgrade/upgrade.taxonomy.test, line 48

Class

UpgradePathTaxonomyTestCase
Test taxonomy upgrades.

Code

public function testTaxonomyUpgrade() {
  $this
    ->assertTrue($this
    ->performUpgrade(), 'The upgrade was completed successfully.');

  // Visit the front page to assert for PHP warning and errors.
  $this
    ->drupalGet('');

  // Check that taxonomy_vocabulary_node_type and taxonomy_term_node have been
  // removed.
  $this
    ->assertFalse(db_table_exists('taxonomy_vocabulary_node_type'), 'taxonomy_vocabulary_node_type has been removed.');
  $this
    ->assertFalse(db_table_exists('taxonomy_term_node'), 'taxonomy_term_node has been removed.');

  // Check that taxonomy_index has not stored nids of unpublished nodes.
  $nids = db_query('SELECT nid from {node} WHERE status = :status', array(
    ':status' => NODE_NOT_PUBLISHED,
  ))
    ->fetchCol();
  $indexed_nids = db_query('SELECT DISTINCT nid from {taxonomy_index}')
    ->fetchCol();
  $this
    ->assertFalse(array_intersect($nids, $indexed_nids), 'No unpublished nid present in taxonomy_index');

  // Check that the node type 'page' has been associated to a taxonomy
  // reference field for each vocabulary.
  $voc_keys = array();
  foreach (taxonomy_get_vocabularies() as $vocab) {
    $voc_keys[] = $vocab->machine_name;
  }
  $instances = $this
    ->instanceVocabularies('node', 'page');
  $inst_keys = array_keys($instances);
  sort($voc_keys);
  sort($inst_keys);
  $this
    ->assertEqual($voc_keys, $inst_keys, 'Node type page has instances for every vocabulary.');

  // Ensure instance variables are getting through.
  foreach (array_unique($instances) as $instance) {
    $field_instance = field_info_instance('node', $instance, 'page');
    $this
      ->assertTrue(isset($field_instance['required']), 'The required setting was preserved during the upgrade path.');
    $this
      ->assertTrue($field_instance['description'], 'The description was preserved during the upgrade path');
  }

  // Node type 'story' was not explicitly in $vocabulary->nodes but
  // each node of type 'story' was associated to one or more terms.
  // Check that the node type 'story' has been associated only to
  // the taxonomyextra field.
  $instances = $this
    ->instanceVocabularies('node', 'story');
  $field_names = array_flip($instances);
  $this
    ->assertEqual(count($field_names), 1, 'Only one taxonomy term field instance exists for story nodes');
  $this
    ->assertEqual(key($field_names), 'taxonomyextra', 'Only the excess taxonomy term field is used on story nodes');

  // Check that the node type 'poll' has been associated to no taxonomy
  // reference field.
  $instances = $this
    ->instanceVocabularies('node', 'poll');
  $this
    ->assertTrue(empty($instances), 'Node type poll has no taxonomy term reference field instances.');

  // Check that each node of type 'page' and 'story' is associated to all the
  // terms except terms whose ID is equal to the node ID or is equal to the
  // node ID subtracted from 49.
  $nodes = node_load_multiple(array(), array(
    'type' => 'page',
  ));
  $nodes += node_load_multiple(array(), array(
    'type' => 'story',
  ));
  $terms = db_select('taxonomy_term_data', 'td')
    ->fields('td')
    ->orderBy('vid')
    ->orderBy('tid')
    ->execute()
    ->fetchAllAssoc('tid');
  field_attach_prepare_view('node', $nodes, 'full');
  foreach ($nodes as $nid => $node) {
    $node->content = field_attach_view('node', $node, 'full');
    $render = drupal_render($node->content);
    $this
      ->drupalSetContent($render);
    $this
      ->verbose($render);
    $vocabulary_seen = array();
    foreach ($terms as $tid => $term) {

      // In our test database, each node is arbitrary associated with all
      // terms except two: one whose tid is ($nid) and one whose tid is
      // (49 - $nid).
      $should_be_displayed = $tid != $nid && $tid + $nid != 49;

      // Only vocabularies 13 to 24 are properly associated with the node
      // type 'page'. All other node types are not associated with any
      // vocabulary, but still are associated with terms. Those terms
      // will be moved to the taxonomy extra field.
      if ($node->type == 'page' && $term->vid >= 13 && $term->vid <= 24) {
        $vocabulary = taxonomy_vocabulary_load($term->vid);
        $field_class = 'field-name-' . strtr('taxonomy_' . $vocabulary->machine_name, '_', '-');
      }
      else {
        $field_class = 'field-name-taxonomyextra';
      }

      // Odd vocabularies are single, so any additional term will be moved
      // to the taxonomy extra field.
      if ($should_be_displayed) {
        if ($term->vid % 2 == 1 && !empty($vocabulary_seen[$term->vid])) {
          $field_class = 'field-name-taxonomyextra';
        }
        $vocabulary_seen[$term->vid] = TRUE;
      }
      $args = array(
        '%name' => $term->name,
        '@field' => $field_class,
        '%nid' => $nid,
      );

      // Use link rather than term name because migrated term names can be
      // substrings of other term names. e.g. "term 1 of vocabulary 2" is
      // found when "term 1 of vocabulary 20" is output.
      $term_path = url('taxonomy/term/' . $term->tid);
      if (!$should_be_displayed) {

        // Look for any link with the term path.
        $links = $this
          ->xpath('//a[@href=:term_path]', array(
          ':term_path' => $term_path,
        ));
        $this
          ->assertFalse($links, format_string('Term %name (@field) is not displayed on node %nid', $args));
      }
      else {

        // Look for a link with the term path inside the correct field.
        // We search for "SPACE + class + SPACE" to avoid matching a substring
        // of the class.
        $links = $this
          ->xpath('//div[contains(concat(" ", normalize-space(@class), " "), :field_class)]//a[@href=:term_path]', array(
          ':field_class' => ' ' . $field_class . ' ',
          ':term_path' => $term_path,
        ));
        $this
          ->assertTrue($links, format_string('Term %name (@field) is displayed on node %nid', $args));
      }
    }

    // nid 1, revision 1 had a bogus record in {term_node} pointing to term
    // ID 0. Make sure we ignored this instead of generating a bogus term.
    if ($node->nid == 1) {
      $link = l($term->name, 'taxonomy/term/0');
      $this
        ->assertNoRaw($link, format_string('Bogus term (tid 0) is not displayed on node 1 vid %old_vid.', $args));
    }

    // The first 12 nodes have two revisions. For nodes with
    // revisions, check that the oldest revision is associated only
    // to terms whose ID is equal to the node ID or 49 less the node ID.
    $revisions = node_revision_list($node);
    if ($node->nid < 13) {
      $this
        ->assertEqual(count($revisions), 2, format_string('Node %nid has two revisions.', $args));
      $last_rev = end($revisions);
      $args['%old_vid'] = $last_rev->vid;
      $node_old = node_load($node->nid, $last_rev->vid);
      field_attach_prepare_view('node', array(
        $node_old->nid => $node_old,
      ), 'full');
      $node_old->content = field_attach_view('node', $node_old, 'full');
      $render = drupal_render($node_old->content);
      $this
        ->drupalSetContent($render);
      $this
        ->verbose($render);
      $term = $terms[$node->nid];
      $link = l($term->name, 'taxonomy/term/' . $term->tid);
      $this
        ->assertRaw($link, format_string('Term %name (@field) is displayed on node %nid vid %old_vid.', $args));
      $term = $terms[49 - $node->nid];
      $link = l($term->name, 'taxonomy/term/' . $term->tid);
      $this
        ->assertRaw($link, format_string('Term %name (@field) is displayed on node %nid %old_vid.', $args));
    }
    else {
      $this
        ->assertEqual(count($revisions), 1, format_string('Node %nid has one revision.', $args));
    }
  }
}