You are here

taxonomy_menu.test in Taxonomy menu 7.2

Defines abstract base test class for the Taxonomy menu module tests.

@TODO Add tests for other configuration options:

  • Edition of nodes.

File

tests/taxonomy_menu.test
View source
<?php

/**
 * @file
 * Defines abstract base test class for the Taxonomy menu module tests.
 *
 * @TODO Add tests for other configuration options:
 *   - Edition of nodes.
 */

/**
 * Abstract class for Taxonomy menu testing. All Taxonomy menu tests should
 * extend this class.
 */
abstract class TaxonomyMenuWebTestCase extends TaxonomyWebTestCase {

  /**
   * A taxonomy vocabulary.
   */
  public $vocabulary;

  /**
   * A hierarchy of taxonomy terms for this vocabulary.
   */
  public $terms_hierarchy;

  /**
   * Asserts that the number of menu links is equal to the number of taxonomy
   * terms for a given menu name.
   *
   * @param $terms
   *   The terms, which are created in this class.
   */
  public function assertEqualNumberTermsMenuLinks($terms_count, $vocabulary, $menu_name) {
    $vid = $vocabulary->vid;

    // Building a query getting the number of menu links for this vocabulary.
    $query = db_select('menu_links', 'ml')
      ->fields('ml')
      ->condition('ml.module', 'taxonomy_menu')
      ->condition('ml.menu_name', $menu_name);
    $query
      ->join('taxonomy_menu', 'tm', 'ml.mlid = tm.mlid');
    $query
      ->condition('tm.vid', $vid, '=');
    $query_count = $query
      ->execute()
      ->rowCount();
    $message = $query_count . ' menu links were found for the ' . $terms_count . ' taxonomy terms of vocabulary ' . $vocabulary->name . '.';
    $this
      ->assertEqual($terms_count, $query_count, $message);
  }

  /**
   * Creates a hierarchy of taxonomy terms for the vocabulary defined in the
   * current class.
   *
   * @return
   *   An array of 7 hierarchised taxonomy term objects.
   *
   *   The hierarchy is as follow:
   *     terms[1]         | depth: 0
   *     -- terms[2]      | depth: 1
   *     -- terms[3]      | depth: 1
   *     ---- terms[4]    | depth: 2
   *     -- terms[5]      | depth: 1
   *     terms[6]         | depth: 0
   *     -- terms[7]      | depth: 1
   *
   * @TODO Add multiple parents when taxonomy_menu can deal with it.
   */
  public function createTermsHierarchy() {
    $terms = array();
    for ($i = 1; $i < 8; $i++) {
      $terms[$i] = $this
        ->createTerm($this->vocabulary);
    }

    // Set the hierarchy by adding parent terms.
    $terms[2]->parent = array(
      $terms[1]->tid,
    );
    taxonomy_term_save($terms[2]);
    $terms[3]->parent = array(
      $terms[1]->tid,
    );
    taxonomy_term_save($terms[3]);
    $terms[4]->parent = array(
      $terms[3]->tid,
    );
    taxonomy_term_save($terms[4]);
    $terms[5]->parent = array(
      $terms[1]->tid,
    );
    taxonomy_term_save($terms[5]);
    $terms[7]->parent = array(
      $terms[6]->tid,
    );
    taxonomy_term_save($terms[7]);
    return $terms;
  }

  /**
   * Fetches the menu item from the database and compare it to the specified
   * array.
   *
   * @param $mlid
   *   The identifier of a menu link.
   * @param $expected_item
   *   An array containing properties to verify.
   */
  public function assertMenuLink($mlid, array $expected_item) {

    // Retrieve menu link.
    $item = db_query('SELECT * FROM {menu_links} WHERE mlid = :mlid', array(
      ':mlid' => $mlid,
    ))
      ->fetchAssoc();
    $options = unserialize($item['options']);
    if (!empty($options['query'])) {
      $item['link_path'] .= '?' . drupal_http_build_query($options['query']);
    }
    if (!empty($options['fragment'])) {
      $item['link_path'] .= '#' . $options['fragment'];
    }
    foreach ($expected_item as $key => $value) {
      $this
        ->assertEqual($item[$key], $value, t('Parameter %key had expected value.', array(
        '%key' => $key,
      )));
    }
  }

  /**
   * Adds a taxonomy reference field to a content type and creates a number of
   * nodes that references different taxonomy terms
   *
   * @param $type string
   *   The content type's machine name to add a term reference field to.
   * @param $terms_index array
   *   An array of term indexes from the terms hierarchy of this class. Each
   *   index will be used to attach a node to this term. Indexes can be duplicated
   *   in order to attach several nodes to the same term.
   */
  public function setUpTermReferenceAndNodes($type, $terms_index) {
    $field = array(
      'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
      'type' => 'taxonomy_term_reference',
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'settings' => array(
        'allowed_values' => array(
          array(
            'vocabulary' => $this->vocabulary->machine_name,
            'parent' => 0,
          ),
        ),
      ),
    );
    field_create_field($field);
    $this->instance = array(
      'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
      'bundle' => $type,
      'entity_type' => 'node',
      'widget' => array(
        'type' => 'options_select',
      ),
      'display' => array(
        'default' => array(
          'type' => 'taxonomy_term_reference_link',
        ),
      ),
    );
    field_create_instance($this->instance);

    // Create nodes that reference each term represented by their indexes.
    foreach ($terms_index as $index) {
      $edit = array();
      $langcode = LANGUAGE_NONE;
      $edit["title"] = $this
        ->randomName();
      $edit["body[{$langcode}][0][value]"] = $this
        ->randomName();
      $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $this->terms_hierarchy[$index]->tid;
      $this
        ->drupalPost('node/add/article', $edit, t('Save'));
    }
  }

}

/**
 * Tests the taxonomy vocabulary interface.
 */
class TaxonomyMenuFunctionalTest extends TaxonomyMenuWebTestCase {

  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Vocabulary interface',
      'description' => 'Test the taxonomy menu vocabulary interface.',
      'group' => 'Taxonomy menu',
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    parent::setUp(array(
      'taxonomy_menu',
    ));

    // Create and login an admin user.
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer taxonomy',
      'administer menu',
      'bypass node access',
    ));
    $this
      ->drupalLogin($admin_user);

    // Create a vocabulary and a hierarchy of taxonomy terms for it.
    $this->vocabulary = $this
      ->createVocabulary();
    $this->terms_hierarchy = $this
      ->createTermsHierarchy();
  }

  /**
   * Save, edit and delete a taxonomy vocabulary using the user interface.
   */
  public function testTaxonomyMenuVocabularyInterface() {
    $menu_name = 'user-menu';
    $vocab = $this->vocabulary->machine_name;

    // Visit the main taxonomy administration page.
    $this
      ->drupalGet('admin/structure/taxonomy/' . $vocab . '/edit');

    // Options for the taxonomy vocabulary edit form.
    $edit = array();

    // Try to submit a vocabulary when menu location is a root menu item.
    $edit['taxonomy_menu[vocab_parent]'] = $menu_name . ':0';
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $this
      ->assertRaw(t('The Taxonomy menu has been created.'));

    // Try to re-submit a vocabulary when an option has changed.
    $edit['taxonomy_menu[options_structure][hide_empty_terms]'] = TRUE;
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertRaw(t('The Taxonomy menu has been updated.'));

    // Try to re-submit a vocabulary without changing any option.
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertRaw(t('The Taxonomy menu was not updated. Nothing to update.'));

    // Try to submit a vocabulary removing the menu location.
    $edit['taxonomy_menu[vocab_parent]'] = '0';
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertRaw(t('The Taxonomy menu has been removed.'));
  }

  /**
   * Re-order terms on the terms' overview page.
   */
  public function testTaxonomyMenuTermsOverviewInterface() {
    $term7 = $this->terms_hierarchy[7];

    // last term of our hierarchy.
    // Submit the main taxonomy administration page.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[sync]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $edit, t('Save'));

    // Visit the terms overview page.
    $this
      ->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);

    // Take last term, place it on top and save.
    $edit = array(
      'tid:' . $term7->tid . ':0[tid]' => $term7->tid,
      'tid:' . $term7->tid . ':0[parent]' => 0,
      'tid:' . $term7->tid . ':0[depth]' => 0,
      'tid:' . $term7->tid . ':0[weight]' => -5,
    );
    $this
      ->drupalPost(NULL, $edit, t('Save'));
    $this
      ->assertRaw(t('The Taxonomy menu has been updated.'));

    // Test "Reset to alphabetical".
    $this
      ->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name, array(), t('Reset to alphabetical'));
    $this
      ->drupalPost(NULL, array(), t('Reset to alphabetical'));
    $this
      ->assertRaw(t('The Taxonomy menu has been updated.'));
  }

  /**
   * Saves, edits and deletes a term using the user interface.
   */
  public function testTaxonomyMenuTermInterface() {
    $menu_name = 'main-menu';

    // Create a taxonomy menu.
    $vocab_settings['taxonomy_menu[vocab_parent]'] = $menu_name . ':0';
    $this
      ->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $vocab_settings, t('Save'));

    // Create a new term from the interface.
    $term_settings = array(
      'name' => $this
        ->randomName(12),
      'description[value]' => $this
        ->randomName(100),
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add', $term_settings, t('Save'));
    $terms = taxonomy_get_term_by_name($term_settings['name']);
    $term = reset($terms);
    $this
      ->assertRaw(t('Added term %term to taxonomy menu %menu_name.', array(
      '%term' => $term_settings['name'],
      '%menu_name' => $menu_name,
    )));

    // Update an existing term from the interface.
    $new_term_settings = array(
      'name' => $this
        ->randomName(12),
      'description[value]' => $this
        ->randomName(100),
    );
    $this
      ->drupalPost('taxonomy/term/' . $term->tid . '/edit', $new_term_settings, t('Save'));
    $this
      ->assertRaw(t('Updated term %term in taxonomy menu %menu_name.', array(
      '%term' => $new_term_settings['name'],
      '%menu_name' => $menu_name,
    )));

    // Delete an existing term from the interface.
    $this
      ->drupalPost('taxonomy/term/' . $term->tid . '/edit', NULL, t('Delete'));
    $this
      ->drupalPost(NULL, NULL, t('Delete'));

    // Confirm deletion of term.
    $this
      ->assertRaw(t('Deleted term %term from taxonomy menu %menu_name.', array(
      '%term' => $new_term_settings['name'],
      '%menu_name' => $menu_name,
    )));
  }

}

/**
 * Tests for taxonomy vocabulary functions.
 */
class TaxonomyMenuUnitTest extends TaxonomyMenuWebTestCase {

  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'CRUD functions',
      'description' => 'Test CRUD functions',
      'group' => 'Taxonomy menu',
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    parent::setUp(array(
      'taxonomy_menu',
    ));

    // Create and login an admin user.
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer taxonomy',
      'administer menu',
      'bypass node access',
    ));
    $this
      ->drupalLogin($admin_user);

    // Create a vocabulary and a hierarchy of taxonomy terms for it.
    $this->vocabulary = $this
      ->createVocabulary();
    $this->terms_hierarchy = $this
      ->createTermsHierarchy();
  }

  /**
   * Tests CRUD functions.
   */
  public function testTaxonomyMenuCRUD() {
    $menu_name = 'main-menu';
    $vocabulary = $this->vocabulary;
    $terms = $this->terms_hierarchy;
    $hierarchy_term = $this->terms_hierarchy[3];

    // Arbitrary term for hierarchy.
    $vid = $this->vocabulary->vid;

    // Ensure that the taxonomy vocabulary form is successfully submitted.
    $edit['taxonomy_menu[vocab_parent]'] = $menu_name . ':0';
    $vocab = $this->vocabulary->machine_name;
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertResponse(200);

    // Ensure that the same number of menu links are created from the taxonomy
    // terms of the vocabulary.
    $this
      ->assertEqualNumberTermsMenuLinks(count($terms), $vocabulary, $menu_name);

    // Ensure that the menu link is updated when the taxonomy term is updated.
    $new_name = $this
      ->randomName();
    $hierarchy_term->name = $new_name;
    taxonomy_term_save($hierarchy_term);
    $this
      ->drupalGet('admin/structure/menu/manage/' . $menu_name);
    $this
      ->assertLink($new_name);

    // Ensure that the menu link is deleted when the taxonomy term is deleted.
    // Hierarchy term [3] has 1 children, if we delete it, 2 taxonomy terms
    // should be deleted.
    $orig_mlid = _taxonomy_menu_get_mlid($hierarchy_term->tid, $vid);
    taxonomy_term_delete($hierarchy_term->tid);
    $this
      ->assertEqualNumberTermsMenuLinks(count($terms) - 2, $vocabulary, $menu_name);
    $menu_link = menu_link_load($orig_mlid);
    $message = 'The menu link ' . $orig_mlid . ' associated to the term ' . $hierarchy_term->tid . ' could not be found.';
    $this
      ->assertFalse($menu_link, $message);
    $mlid = _taxonomy_menu_get_mlid($hierarchy_term->tid, $vid);
    $message = 'The ( mlid = ' . $orig_mlid . ' / tid = ' . $hierarchy_term->tid . ') association could not be found in {taxonomy_menu} table.';
    $this
      ->assertFalse($mlid, $message);

    // Ensure that all menu links and all associations in {taxonomy_menu} table
    // are deleted when a vocabulary is deleted.
    $mlids = _taxonomy_menu_get_menu_items($vid);
    taxonomy_vocabulary_delete($vid);
    $this
      ->assertEqualNumberTermsMenuLinks(0, $vocabulary, $menu_name);
  }

  /**
   * Tests the hierarchy of menu links in a menu.
   */
  public function testTaxonomyMenuTermsHierarchy() {
    $vocab_machine_name = $this->vocabulary->machine_name;
    $vid = $this->vocabulary->vid;
    $edit = array();

    // Settings
    $edit['taxonomy_menu[vocab_parent]'] = 'main-menu:0';
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab_machine_name . '/edit', $edit, t('Save'));
    $this
      ->assertResponse(200);

    // Given a taxonomy term, which id is tid:
    //   - ptid      -->  - plid
    //     - tid     -->    - mlid
    // Do the following verification for each term in the hierarchy; the ending
    // plid determined by the methods below should be equal.
    //   - method1: tid --> mlid --> plid
    //   - method2: tid --> ptid --> plid
    foreach ($this->terms_hierarchy as $term) {

      // 1. Get plid by getting the associated mlid for the term tid.
      $mlid = _taxonomy_menu_get_mlid($term->tid, $vid);
      if ($mlid) {
        $menu_link = menu_link_load($mlid);
        $plid_from_mlid = $menu_link['plid'];

        // 2. Get plid by getting the associated mlid for the parent term ptid.
        // We don't handle multiple parents, break after first one.
        $parents = taxonomy_get_parents($term->tid);
        if (!empty($parents)) {
          foreach ($parents as $ptid => $parent) {
            $plid_from_ptid = _taxonomy_menu_get_mlid($ptid, $vid);

            // Assert that both plid found by the two different methods are equal.
            $message = 'Parent mlids from taxonomy term ' . $term->tid . ' are a match.';
            $this
              ->assertEqual($plid_from_mlid, $plid_from_ptid, $message);
            break;
          }
        }
        else {

          // Current term has no parent term. This means that the name of the
          // vocabulary should be associated to the 'navigation' root.
          // Menu link of the current term as defined by taxonomy menu table.
          $this
            ->assertEqual($menu_link['plid'], 0);
        }
      }
      else {
        $this
          ->fail("mlid for taxonomy term " . $term->tid . " could not be found.");
      }
    }
  }

  /**
   * Tests creation of menu links in a custom menu.
   */
  public function testTaxonomyMenuCustomMenu() {
    $vocabulary = $this->vocabulary;
    $terms = $this->terms_hierarchy;
    $custom_menu_name = $this
      ->randomName(16);
    $menu_machine_name = drupal_substr(hash('sha256', $custom_menu_name), 0, MENU_MAX_MENU_NAME_LENGTH_UI);

    // Submit the menu creation form.
    $menu_edit = array();
    $menu_edit['title'] = $custom_menu_name;
    $menu_edit['menu_name'] = $menu_machine_name;
    $this
      ->drupalPost('admin/structure/menu/add', $menu_edit, 'Save');
    $this
      ->assertResponse(200);

    // Submit the vocabulary edit form.
    $vocab_edit = array();
    $vocab_edit['taxonomy_menu[vocab_parent]'] = 'menu-' . $menu_machine_name . ':0';
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/edit', $vocab_edit, 'Save');
    $this
      ->assertResponse(200);

    // Check that the menu links were created in the custom menu.
    $this
      ->assertEqualNumberTermsMenuLinks(count($terms), $vocabulary, 'menu-' . $menu_machine_name);
  }

}

/**
 * Tests Taxonomy menu configuration options.
 */
class TaxonomyMenuConfigurationTest extends TaxonomyMenuWebTestCase {

  /**
   * Implementation of getInfo().
   */
  public static function getInfo() {
    return array(
      'name' => 'Configuration options',
      'description' => 'Test configuration options.',
      'group' => 'Taxonomy menu',
    );
  }

  /**
   * Implementation of setUp().
   */
  function setUp() {
    parent::setUp(array(
      'taxonomy_menu',
    ));

    // Create and login an admin user.
    $admin_user = $this
      ->drupalCreateUser(array(
      'administer taxonomy',
      'administer menu',
      'bypass node access',
    ));
    $this
      ->drupalLogin($admin_user);

    // Create a vocabulary and a hierarchy of taxonomy terms for it.
    $this->vocabulary = $this
      ->createVocabulary();
    $this->terms_hierarchy = $this
      ->createTermsHierarchy();
  }

  /**
   * Tests Taxonommy Menu sync option.
   */
  public function testTaxonomyMenuSyncOption() {
    $vocab = $this->vocabulary->machine_name;

    // Set settings (no sync on main-menu).
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[sync]' => FALSE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertResponse(200);

    // Prepare changes.
    $new_name = $this
      ->randomName(12);
    $test_term = $this->terms_hierarchy[3];

    // Arbitrary term from hierarchy
    $test_term->name = $new_name;

    // Save new term's name with sync option off.
    taxonomy_term_save($test_term);
    $mlid = _taxonomy_menu_get_mlid($test_term->tid, $this->vocabulary->vid);
    $menu_link = menu_link_load($mlid);
    $this
      ->assertNotEqual($new_name, $menu_link['link_title']);

    // Switch to sync option on and save.
    $edit['taxonomy_menu[sync]'] = TRUE;
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $this
      ->assertResponse(200);
    $mlid = _taxonomy_menu_get_mlid($test_term->tid, $this->vocabulary->vid);
    $menu_link = menu_link_load($mlid);
    $this
      ->assertEqual($new_name, $menu_link['link_title']);
  }

  /**
   * Tests Taxonommy Menu expand option.
   */
  public function testTaxonomyMenuExpandedOption() {
    $vocab = $this->vocabulary->machine_name;

    // Set settings on expanded.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_structure][expanded]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));

    // Build the base query.
    $base_query = db_select('menu_links', 'ml');
    $base_query
      ->join('taxonomy_menu', 'tm', 'ml.mlid = tm.mlid');
    $base_query
      ->fields('ml')
      ->condition('tm.vid', $this->vocabulary->vid)
      ->condition('ml.module', 'taxonomy_menu');

    // Assert that menu links are expanded.
    $query = $base_query
      ->condition('ml.expanded', TRUE);
    $row_count = $query
      ->execute()
      ->rowCount();
    $this
      ->assertEqual(count($this->terms_hierarchy), $row_count);

    // Set settings on not expanded.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_structure][expanded]' => FALSE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));

    // Assert that menu links are not expanded anymore.
    $query = $base_query
      ->condition('ml.expanded', FALSE);
    $row_count = $query
      ->execute()
      ->rowCount();
    $this
      ->assertEqual(0, $row_count);
  }

  /**
   * Tests Taxonommy Menu "Term description" option.
   */
  public function testTaxonomyMenuTermDescriptionOption() {
    $vocab = $this->vocabulary->machine_name;

    // Set settings on expanded.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_markup][term_item_description]' => FALSE,
      'taxonomy_menu[options_markup][display_title_attr]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));

    // Assert that menu links does not have the term description.
    $term = $this->terms_hierarchy[3];
    $mlid = _taxonomy_menu_get_mlid($term->tid, $this->vocabulary->vid);
    $menu_link = menu_link_load($mlid);
    $menu_link_title = $menu_link['options']['attributes']['title'];
    $this
      ->assertEqual($menu_link_title, '');

    // Assert that menu links does have the term description, when the option is
    // checked.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_markup][term_item_description]' => TRUE,
      'taxonomy_menu[options_markup][display_title_attr]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $menu_link = menu_link_load($mlid);
    $menu_link_title = $menu_link['options']['attributes']['title'];
    $this
      ->assertEqual($menu_link_title, trim($term->description));

    // Assert that menu links does not have the term description, when the option
    // for displaying a description is on but the display title option is off.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_markup][term_item_description]' => TRUE,
      'taxonomy_menu[options_markup][display_title_attr]' => FALSE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $menu_link = menu_link_load($mlid);
    $menu_link_title = $menu_link['options']['attributes']['title'];
    $this
      ->assertEqual($menu_link_title, '');
  }

  /**
   * Tests Taxonommy Menu "Flatten" option.
   */
  public function testTaxonomyMenuFlattenOption() {
    $vocab = $this->vocabulary->machine_name;

    // Set settings.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_structure][flat]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));

    // Assert that all of the menu links have no children with the root being
    // the menu.
    $query = db_select('menu_links', 'ml');
    $query
      ->join('taxonomy_menu', 'tm', 'ml.mlid = tm.mlid');
    $query
      ->fields('ml');
    $query
      ->condition('tm.vid', $this->vocabulary->vid)
      ->condition('ml.menu_name', 'main-menu')
      ->condition('ml.module', 'taxonomy_menu')
      ->condition('ml.has_children', 0)
      ->condition('ml.plid', 0);
    $row_count = $query
      ->execute()
      ->rowCount();
    $this
      ->assertEqual(count($this->terms_hierarchy), $row_count);

    // Assert that all of the menu links have no children with the root being
    // a menu item.
    $item = array(
      'menu_name' => 'main-menu',
      'weight' => 0,
      'link_title' => 'test',
      'link_path' => '<front>',
      'module' => 'taxonomy_menu',
    );
    $mlid = menu_link_save($item);
    menu_cache_clear('main-menu');
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:' . $mlid,
      'taxonomy_menu[options_structure][flat]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $vocab . '/edit', $edit, t('Save'));
    $query = db_select('menu_links', 'ml');
    $query
      ->join('taxonomy_menu', 'tm', 'ml.mlid = tm.mlid');
    $query
      ->fields('ml');
    $query
      ->condition('tm.vid', $this->vocabulary->vid)
      ->condition('ml.menu_name', 'main-menu')
      ->condition('ml.module', 'taxonomy_menu')
      ->condition('ml.has_children', 0)
      ->condition('ml.plid', $mlid);
    $row_count = $query
      ->execute()
      ->rowCount();
    $this
      ->assertEqual(count($this->terms_hierarchy), $row_count);
  }

  /**
   * Tests Taxonommy Menu "Hide Empty terms" option.
   */
  public function testTaxonomyMenuHideEmptyTerms() {
    $voc_machine_name = $this->vocabulary->machine_name;

    // Create several nodes and attach them to different terms of our hierarchy
    // in order to match the following scheme.

    /** terms[1]         | depth: 0 | 0 node  -> hidden
     * -- terms[2]       | depth: 1 | 0 node  -> hidden
     * -- terms[3]       | depth: 1 | 2 nodes -> displayed
     * ---- terms[4]     | depth: 2 | 0 node  -> hidden
     * -- terms[5]       | depth: 1 | 1 node  -> displayed
     * terms[6]          | depth: 0 | 0 node  -> hidden
     * -- terms[7]       | depth: 1 | 0 node  -> hidden   */
    $this
      ->setUpTermReferenceAndNodes('article', array(
      3,
      3,
      5,
    ));

    // Set settings (don't hide empty terms) and save.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_structure][hide_empty_terms]' => FALSE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $voc_machine_name . '/edit', $edit, t('Save'));

    // Assert that all links are displayed.
    foreach ($this->terms_hierarchy as $term) {
      $mlid = _taxonomy_menu_get_mlid($term->tid, $this->vocabulary->vid);
      if ($mlid) {
        $this
          ->assertMenuLink($mlid, array(
          'hidden' => FALSE,
        ));
      }
      else {
        $this
          ->fail('No mlid could be found for the term ' . $term->tid);
      }
    }

    // Set settings (hide empty terms) and save.
    $edit['taxonomy_menu[options_structure][hide_empty_terms]'] = TRUE;
    $this
      ->drupalPost('admin/structure/taxonomy/' . $voc_machine_name . '/edit', $edit, t('Save'));

    // Assert that the hidden property of the taxonomy menu's menu links are
    // set according to the scheme.
    $visible_terms_index = array(
      3,
      5,
    );
    $index = 1;
    foreach ($this->terms_hierarchy as $term) {
      $mlid = _taxonomy_menu_get_mlid($term->tid, $this->vocabulary->vid);
      if ($mlid) {
        if (in_array($index, $visible_terms_index)) {
          $this
            ->assertMenuLink($mlid, array(
            'hidden' => FALSE,
          ));
        }
        else {
          $this
            ->assertMenuLink($mlid, array(
            'hidden' => TRUE,
          ));
        }
      }
      else {
        $this
          ->fail('No mlid could be found for the term ' . $term->tid);
      }
      $index++;
    }
  }

  /**
   * Tests Taxonommy Menu "Node count" option.
   *
   * @TODO Add a test for recursive count.
   */
  public function testTaxonomyMenuCountNodes() {
    $voc_machine_name = $this->vocabulary->machine_name;

    /*
      Create several nodes and attach them to different terms of our hierarchy
      in order to match the following scheme. We don't use "hide empty terms".
      option.

      terms[1]          | depth: 0 | 0 node attached
      -- terms[2]       | depth: 1 | 0 node attached
      -- terms[3]       | depth: 1 | 2 nodes attached
      ---- terms[4]     | depth: 2 | 2 nodes attached
      -- terms[5]       | depth: 1 | 1 node attached
      terms[6]          | depth: 0 | 1 node attached
      -- terms[7]       | depth: 1 | 0 node attached

      We expect the following result for number of items:
      - terms[1]: count is 0
      - terms[3]: count is 2
      - terms[4]: count is 2
      - terms[5]: count is 1
      - terms[6]: count is 1
      - Others  : count is 0
    */
    $this
      ->setUpTermReferenceAndNodes('article', array(
      3,
      3,
      4,
      4,
      5,
      6,
    ));

    // Set settings and save.
    $edit = array(
      'taxonomy_menu[vocab_parent]' => 'main-menu:0',
      'taxonomy_menu[options_structure][hide_empty_terms]' => FALSE,
      'taxonomy_menu[options_markup][display_num]' => TRUE,
    );
    $this
      ->drupalPost('admin/structure/taxonomy/' . $voc_machine_name . '/edit', $edit, t('Save'));

    // Assert that the count is correct in the menu links according to the scheme.
    $index = 1;
    $positive_count_terms_index = array(
      3,
      4,
      5,
      6,
    );
    $visible_item = array(
      'hidden' => FALSE,
    );
    foreach ($this->terms_hierarchy as $term) {
      $mlid = _taxonomy_menu_get_mlid($term->tid, $this->vocabulary->vid);
      $menu_link = menu_link_load($mlid);
      if ($mlid) {
        switch ($index) {
          case '3':
          case '4':
            $count = 2;
            break;
          case '5':
          case '6':
            $count = 1;
            break;
          default:
            $count = 0;
            break;
        }
        if (in_array($index, $positive_count_terms_index)) {
          $this
            ->assertMenuLink($mlid, array(
            'link_title' => $term->name . ' (' . $count . ')',
          ));
        }
        else {
          $this
            ->assertMenuLink($mlid, array(
            'link_title' => $term->name,
          ));
        }
      }
      else {
        $this
          ->fail('No mlid could be found for the term ' . $term->tid);
      }
      $index++;
    }
  }

}

Classes

Namesort descending Description
TaxonomyMenuConfigurationTest Tests Taxonomy menu configuration options.
TaxonomyMenuFunctionalTest Tests the taxonomy vocabulary interface.
TaxonomyMenuUnitTest Tests for taxonomy vocabulary functions.
TaxonomyMenuWebTestCase Abstract class for Taxonomy menu testing. All Taxonomy menu tests should extend this class.