cms/drupal/modules/taxonomy/taxonomy.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for taxonomy.module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Provides common helper methods for Taxonomy module tests.
       
    10  */
       
    11 class TaxonomyWebTestCase extends DrupalWebTestCase {
       
    12 
       
    13   /**
       
    14    * Returns a new vocabulary with random properties.
       
    15    */
       
    16   function createVocabulary() {
       
    17     // Create a vocabulary.
       
    18     $vocabulary = new stdClass();
       
    19     $vocabulary->name = $this->randomName();
       
    20     $vocabulary->description = $this->randomName();
       
    21     $vocabulary->machine_name = drupal_strtolower($this->randomName());
       
    22     $vocabulary->help = '';
       
    23     $vocabulary->nodes = array('article' => 'article');
       
    24     $vocabulary->weight = mt_rand(0, 10);
       
    25     taxonomy_vocabulary_save($vocabulary);
       
    26     return $vocabulary;
       
    27   }
       
    28 
       
    29   /**
       
    30    * Returns a new term with random properties in vocabulary $vid.
       
    31    */
       
    32   function createTerm($vocabulary) {
       
    33     $term = new stdClass();
       
    34     $term->name = $this->randomName();
       
    35     $term->description = $this->randomName();
       
    36     // Use the first available text format.
       
    37     $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField();
       
    38     $term->vid = $vocabulary->vid;
       
    39     taxonomy_term_save($term);
       
    40     return $term;
       
    41   }
       
    42 
       
    43 }
       
    44 
       
    45 /**
       
    46  * Tests the taxonomy vocabulary interface.
       
    47  */
       
    48 class TaxonomyVocabularyFunctionalTest extends TaxonomyWebTestCase {
       
    49 
       
    50   public static function getInfo() {
       
    51     return array(
       
    52       'name' => 'Taxonomy vocabulary interface',
       
    53       'description' => 'Test the taxonomy vocabulary interface.',
       
    54       'group' => 'Taxonomy',
       
    55     );
       
    56   }
       
    57 
       
    58   function setUp() {
       
    59     parent::setUp();
       
    60     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy'));
       
    61     $this->drupalLogin($this->admin_user);
       
    62     $this->vocabulary = $this->createVocabulary();
       
    63   }
       
    64 
       
    65   /**
       
    66    * Create, edit and delete a vocabulary via the user interface.
       
    67    */
       
    68   function testVocabularyInterface() {
       
    69     // Visit the main taxonomy administration page.
       
    70     $this->drupalGet('admin/structure/taxonomy');
       
    71 
       
    72     // Create a new vocabulary.
       
    73     $this->clickLink(t('Add vocabulary'));
       
    74     $edit = array();
       
    75     $machine_name = drupal_strtolower($this->randomName());
       
    76     $edit['name'] = $this->randomName();
       
    77     $edit['description'] = $this->randomName();
       
    78     $edit['machine_name'] = $machine_name;
       
    79     $this->drupalPost(NULL, $edit, t('Save'));
       
    80     $this->assertRaw(t('Created new vocabulary %name.', array('%name' => $edit['name'])), 'Vocabulary created successfully.');
       
    81 
       
    82     // Edit the vocabulary.
       
    83     $this->drupalGet('admin/structure/taxonomy');
       
    84     $this->assertText($edit['name'], 'Vocabulary found in the vocabulary overview listing.');
       
    85     $this->clickLink(t('edit vocabulary'));
       
    86     $edit = array();
       
    87     $edit['name'] = $this->randomName();
       
    88     $this->drupalPost(NULL, $edit, t('Save'));
       
    89     $this->drupalGet('admin/structure/taxonomy');
       
    90     $this->assertText($edit['name'], 'Vocabulary found in the vocabulary overview listing.');
       
    91 
       
    92     // Try to submit a vocabulary with a duplicate machine name.
       
    93     $edit['machine_name'] = $machine_name;
       
    94     $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
       
    95     $this->assertText(t('The machine-readable name is already in use. It must be unique.'));
       
    96 
       
    97     // Try to submit an invalid machine name.
       
    98     $edit['machine_name'] = '!&^%';
       
    99     $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
       
   100     $this->assertText(t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
       
   101 
       
   102     // Ensure that vocabulary titles are escaped properly.
       
   103     $edit = array();
       
   104     $edit['name'] = 'Don\'t Panic';
       
   105     $edit['description'] = $this->randomName();
       
   106     $edit['machine_name'] = 'don_t_panic';
       
   107     $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
       
   108 
       
   109     $site_name = variable_get('site_name', 'Drupal');
       
   110     $this->drupalGet('admin/structure/taxonomy/don_t_panic');
       
   111     $this->assertTitle(t('Don\'t Panic | @site-name', array('@site-name' => $site_name)));
       
   112     $this->assertNoTitle(t('Don&#039;t Panic | @site-name', array('@site-name' => $site_name)));
       
   113   }
       
   114 
       
   115   /**
       
   116    * Changing weights on the vocabulary overview with two or more vocabularies.
       
   117    */
       
   118   function testTaxonomyAdminChangingWeights() {
       
   119     // Create some vocabularies.
       
   120     for ($i = 0; $i < 10; $i++) {
       
   121       $this->createVocabulary();
       
   122     }
       
   123     // Get all vocabularies and change their weights.
       
   124     $vocabularies = taxonomy_get_vocabularies();
       
   125     $edit = array();
       
   126     foreach ($vocabularies as $key => $vocabulary) {
       
   127       $vocabulary->weight = -$vocabulary->weight;
       
   128       $vocabularies[$key]->weight = $vocabulary->weight;
       
   129       $edit[$key . '[weight]'] = $vocabulary->weight;
       
   130     }
       
   131     // Saving the new weights via the interface.
       
   132     $this->drupalPost('admin/structure/taxonomy', $edit, t('Save'));
       
   133 
       
   134     // Load the vocabularies from the database.
       
   135     $new_vocabularies = taxonomy_get_vocabularies();
       
   136 
       
   137     // Check that the weights are saved in the database correctly.
       
   138     foreach ($vocabularies as $key => $vocabulary) {
       
   139       $this->assertEqual($new_vocabularies[$key]->weight, $vocabularies[$key]->weight, 'The vocabulary weight was changed.');
       
   140     }
       
   141   }
       
   142 
       
   143   /**
       
   144    * Test the vocabulary overview with no vocabularies.
       
   145    */
       
   146   function testTaxonomyAdminNoVocabularies() {
       
   147     // Delete all vocabularies.
       
   148     $vocabularies = taxonomy_get_vocabularies();
       
   149     foreach ($vocabularies as $key => $vocabulary) {
       
   150       taxonomy_vocabulary_delete($key);
       
   151     }
       
   152     // Confirm that no vocabularies are found in the database.
       
   153     $this->assertFalse(taxonomy_get_vocabularies(), 'No vocabularies found in the database.');
       
   154     $this->drupalGet('admin/structure/taxonomy');
       
   155     // Check the default message for no vocabularies.
       
   156     $this->assertText(t('No vocabularies available.'), 'No vocabularies were found.');
       
   157   }
       
   158 
       
   159   /**
       
   160    * Deleting a vocabulary.
       
   161    */
       
   162   function testTaxonomyAdminDeletingVocabulary() {
       
   163     // Create a vocabulary.
       
   164     $edit = array(
       
   165       'name' => $this->randomName(),
       
   166       'machine_name' => drupal_strtolower($this->randomName()),
       
   167     );
       
   168     $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
       
   169     $this->assertText(t('Created new vocabulary'), 'New vocabulary was created.');
       
   170 
       
   171     // Check the created vocabulary.
       
   172     $vocabularies = taxonomy_get_vocabularies();
       
   173     $vocabularies_keys = array_keys($vocabularies);
       
   174     $vid = $vocabularies[end($vocabularies_keys)]->vid;
       
   175     entity_get_controller('taxonomy_vocabulary')->resetCache();
       
   176     $vocabulary = taxonomy_vocabulary_load($vid);
       
   177     $this->assertTrue($vocabulary, 'Vocabulary found in database.');
       
   178 
       
   179     // Delete the vocabulary.
       
   180     $edit = array();
       
   181     $this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/edit', $edit, t('Delete'));
       
   182     $this->assertRaw(t('Are you sure you want to delete the vocabulary %name?', array('%name' => $vocabulary->name)), '[confirm deletion] Asks for confirmation.');
       
   183     $this->assertText(t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'), '[confirm deletion] Inform that all terms will be deleted.');
       
   184 
       
   185     // Confirm deletion.
       
   186     $this->drupalPost(NULL, NULL, t('Delete'));
       
   187     $this->assertRaw(t('Deleted vocabulary %name.', array('%name' => $vocabulary->name)), 'Vocabulary deleted.');
       
   188     entity_get_controller('taxonomy_vocabulary')->resetCache();
       
   189     $this->assertFalse(taxonomy_vocabulary_load($vid), 'Vocabulary is not found in the database.');
       
   190   }
       
   191 
       
   192 }
       
   193 
       
   194 /**
       
   195  * Tests for taxonomy vocabulary functions.
       
   196  */
       
   197 class TaxonomyVocabularyTestCase extends TaxonomyWebTestCase {
       
   198 
       
   199   public static function getInfo() {
       
   200     return array(
       
   201       'name' => 'Taxonomy vocabularies',
       
   202       'description' => 'Test loading, saving and deleting vocabularies.',
       
   203       'group' => 'Taxonomy',
       
   204     );
       
   205   }
       
   206 
       
   207   function setUp() {
       
   208     parent::setUp('taxonomy', 'field_test');
       
   209     $admin_user = $this->drupalCreateUser(array('create article content', 'administer taxonomy'));
       
   210     $this->drupalLogin($admin_user);
       
   211     $this->vocabulary = $this->createVocabulary();
       
   212   }
       
   213 
       
   214   /**
       
   215    * Ensure that when an invalid vocabulary vid is loaded, it is possible
       
   216    * to load the same vid successfully if it subsequently becomes valid.
       
   217    */
       
   218   function testTaxonomyVocabularyLoadReturnFalse() {
       
   219     // Load a vocabulary that doesn't exist.
       
   220     $vocabularies = taxonomy_get_vocabularies();
       
   221     $vid = count($vocabularies) + 1;
       
   222     $vocabulary = taxonomy_vocabulary_load($vid);
       
   223     // This should not return an object because no such vocabulary exists.
       
   224     $this->assertTrue(empty($vocabulary), 'No object loaded.');
       
   225 
       
   226     // Create a new vocabulary.
       
   227     $this->createVocabulary();
       
   228     // Load the vocabulary with the same $vid from earlier.
       
   229     // This should return a vocabulary object since it now matches a real vid.
       
   230     $vocabulary = taxonomy_vocabulary_load($vid);
       
   231     $this->assertTrue(!empty($vocabulary) && is_object($vocabulary), 'Vocabulary is an object.');
       
   232     $this->assertEqual($vocabulary->vid, $vid, 'Valid vocabulary vid is the same as our previously invalid one.');
       
   233   }
       
   234 
       
   235   /**
       
   236    * Test deleting a taxonomy that contains terms.
       
   237    */
       
   238   function testTaxonomyVocabularyDeleteWithTerms() {
       
   239     // Delete any existing vocabularies.
       
   240     foreach (taxonomy_get_vocabularies() as $vocabulary) {
       
   241       taxonomy_vocabulary_delete($vocabulary->vid);
       
   242     }
       
   243 
       
   244     // Assert that there are no terms left.
       
   245     $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
       
   246 
       
   247     // Create a new vocabulary and add a few terms to it.
       
   248     $vocabulary = $this->createVocabulary();
       
   249     $terms = array();
       
   250     for ($i = 0; $i < 5; $i++) {
       
   251       $terms[$i] = $this->createTerm($vocabulary);
       
   252     }
       
   253 
       
   254     // Set up hierarchy. term 2 is a child of 1 and 4 a child of 1 and 2.
       
   255     $terms[2]->parent = array($terms[1]->tid);
       
   256     taxonomy_term_save($terms[2]);
       
   257     $terms[4]->parent = array($terms[1]->tid, $terms[2]->tid);
       
   258     taxonomy_term_save($terms[4]);
       
   259 
       
   260     // Assert that there are now 5 terms.
       
   261     $this->assertEqual(5, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
       
   262 
       
   263     taxonomy_vocabulary_delete($vocabulary->vid);
       
   264 
       
   265     // Assert that there are no terms left.
       
   266     $this->assertEqual(0, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
       
   267   }
       
   268 
       
   269   /**
       
   270    * Ensure that the vocabulary static reset works correctly.
       
   271    */
       
   272   function testTaxonomyVocabularyLoadStaticReset() {
       
   273     $original_vocabulary = taxonomy_vocabulary_load($this->vocabulary->vid);
       
   274     $this->assertTrue(is_object($original_vocabulary), 'Vocabulary loaded successfully.');
       
   275     $this->assertEqual($this->vocabulary->name, $original_vocabulary->name, 'Vocabulary loaded successfully.');
       
   276 
       
   277     // Change the name and description.
       
   278     $vocabulary = $original_vocabulary;
       
   279     $vocabulary->name = $this->randomName();
       
   280     $vocabulary->description = $this->randomName();
       
   281     taxonomy_vocabulary_save($vocabulary);
       
   282 
       
   283     // Load the vocabulary.
       
   284     $new_vocabulary = taxonomy_vocabulary_load($original_vocabulary->vid);
       
   285     $this->assertEqual($new_vocabulary->name, $vocabulary->name);
       
   286     $this->assertEqual($new_vocabulary->name, $vocabulary->name);
       
   287 
       
   288     // Delete the vocabulary.
       
   289     taxonomy_vocabulary_delete($this->vocabulary->vid);
       
   290     $vocabularies = taxonomy_get_vocabularies();
       
   291     $this->assertTrue(!isset($vocabularies[$this->vocabulary->vid]), 'The vocabulary was deleted.');
       
   292   }
       
   293 
       
   294   /**
       
   295    * Tests for loading multiple vocabularies.
       
   296    */
       
   297   function testTaxonomyVocabularyLoadMultiple() {
       
   298 
       
   299     // Delete any existing vocabularies.
       
   300     foreach (taxonomy_get_vocabularies() as $vocabulary) {
       
   301       taxonomy_vocabulary_delete($vocabulary->vid);
       
   302     }
       
   303 
       
   304     // Create some vocabularies and assign weights.
       
   305     $vocabulary1 = $this->createVocabulary();
       
   306     $vocabulary1->weight = 0;
       
   307     taxonomy_vocabulary_save($vocabulary1);
       
   308     $vocabulary2 = $this->createVocabulary();
       
   309     $vocabulary2->weight = 1;
       
   310     taxonomy_vocabulary_save($vocabulary2);
       
   311     $vocabulary3 = $this->createVocabulary();
       
   312     $vocabulary3->weight = 2;
       
   313     taxonomy_vocabulary_save($vocabulary3);
       
   314 
       
   315     // Fetch the names for all vocabularies, confirm that they are keyed by
       
   316     // machine name.
       
   317     $names = taxonomy_vocabulary_get_names();
       
   318     $this->assertEqual($names[$vocabulary1->machine_name]->name, $vocabulary1->name, 'Vocabulary 1 name found.');
       
   319 
       
   320     // Fetch all of the vocabularies using taxonomy_get_vocabularies().
       
   321     // Confirm that the vocabularies are ordered by weight.
       
   322     $vocabularies = taxonomy_get_vocabularies();
       
   323     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, 'Vocabulary was found in the vocabularies array.');
       
   324     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, 'Vocabulary was found in the vocabularies array.');
       
   325     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, 'Vocabulary was found in the vocabularies array.');
       
   326 
       
   327     // Fetch the vocabularies with taxonomy_vocabulary_load_multiple(), specifying IDs.
       
   328     // Ensure they are returned in the same order as the original array.
       
   329     $vocabularies = taxonomy_vocabulary_load_multiple(array($vocabulary3->vid, $vocabulary2->vid, $vocabulary1->vid));
       
   330     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, 'Vocabulary loaded successfully by ID.');
       
   331     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, 'Vocabulary loaded successfully by ID.');
       
   332     $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, 'Vocabulary loaded successfully by ID.');
       
   333 
       
   334     // Fetch vocabulary 1 by name.
       
   335     $vocabulary = current(taxonomy_vocabulary_load_multiple(array(), array('name' => $vocabulary1->name)));
       
   336     $this->assertEqual($vocabulary->vid, $vocabulary1->vid, 'Vocabulary loaded successfully by name.');
       
   337 
       
   338     // Fetch vocabulary 1 by name and ID.
       
   339     $this->assertEqual(current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('name' => $vocabulary1->name)))->vid, $vocabulary1->vid, 'Vocabulary loaded successfully by name and ID.');
       
   340   }
       
   341 
       
   342   /**
       
   343    * Tests that machine name changes are properly reflected.
       
   344    */
       
   345   function testTaxonomyVocabularyChangeMachineName() {
       
   346     // Add a field instance to the vocabulary.
       
   347     $field = array(
       
   348       'field_name' => 'field_test',
       
   349       'type' => 'test_field',
       
   350     );
       
   351     field_create_field($field);
       
   352     $instance = array(
       
   353       'field_name' => 'field_test',
       
   354       'entity_type' => 'taxonomy_term',
       
   355       'bundle' => $this->vocabulary->machine_name,
       
   356     );
       
   357     field_create_instance($instance);
       
   358 
       
   359     // Change the machine name.
       
   360     $new_name = drupal_strtolower($this->randomName());
       
   361     $this->vocabulary->machine_name = $new_name;
       
   362     taxonomy_vocabulary_save($this->vocabulary);
       
   363 
       
   364     // Check that the field instance is still attached to the vocabulary.
       
   365     $this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), 'The bundle name was updated correctly.');
       
   366   }
       
   367 
       
   368   /**
       
   369    * Test uninstall and reinstall of the taxonomy module.
       
   370    */
       
   371   function testUninstallReinstall() {
       
   372     // Fields and field instances attached to taxonomy term bundles should be
       
   373     // removed when the module is uninstalled.
       
   374     $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
       
   375     $this->field = array('field_name' => $this->field_name, 'type' => 'text', 'cardinality' => 4);
       
   376     $this->field = field_create_field($this->field);
       
   377     $this->instance = array(
       
   378       'field_name' => $this->field_name,
       
   379       'entity_type' => 'taxonomy_term',
       
   380       'bundle' => $this->vocabulary->machine_name,
       
   381       'label' => $this->randomName() . '_label',
       
   382     );
       
   383     field_create_instance($this->instance);
       
   384 
       
   385     module_disable(array('taxonomy'));
       
   386     require_once DRUPAL_ROOT . '/includes/install.inc';
       
   387     drupal_uninstall_modules(array('taxonomy'));
       
   388     module_enable(array('taxonomy'));
       
   389 
       
   390     // Now create a vocabulary with the same name. All field instances
       
   391     // connected to this vocabulary name should have been removed when the
       
   392     // module was uninstalled. Creating a new field with the same name and
       
   393     // an instance of this field on the same bundle name should be successful.
       
   394     unset($this->vocabulary->vid);
       
   395     taxonomy_vocabulary_save($this->vocabulary);
       
   396     unset($this->field['id']);
       
   397     field_create_field($this->field);
       
   398     field_create_instance($this->instance);
       
   399   }
       
   400 
       
   401 }
       
   402 
       
   403 /**
       
   404  * Unit tests for taxonomy term functions.
       
   405  */
       
   406 class TaxonomyTermFunctionTestCase extends TaxonomyWebTestCase {
       
   407 
       
   408   public static function getInfo() {
       
   409     return array(
       
   410       'name' => 'Taxonomy term unit tests',
       
   411       'description' => 'Unit tests for taxonomy term functions.',
       
   412       'group' => 'Taxonomy',
       
   413     );
       
   414   }
       
   415 
       
   416   function testTermDelete() {
       
   417     $vocabulary = $this->createVocabulary();
       
   418     $valid_term = $this->createTerm($vocabulary);
       
   419     // Delete a valid term.
       
   420     taxonomy_term_delete($valid_term->tid);
       
   421     $terms = taxonomy_term_load_multiple(array(), array('vid' => $vocabulary->vid));
       
   422     $this->assertTrue(empty($terms), 'Vocabulary is empty after deletion.');
       
   423 
       
   424     // Delete an invalid term. Should not throw any notices.
       
   425     taxonomy_term_delete(42);
       
   426   }
       
   427 
       
   428   /**
       
   429    * Test a taxonomy with terms that have multiple parents of different depths.
       
   430    */
       
   431   function testTaxonomyVocabularyTree() {
       
   432     // Create a new vocabulary with 6 terms.
       
   433     $vocabulary = $this->createVocabulary();
       
   434     $term = array();
       
   435     for ($i = 0; $i < 6; $i++) {
       
   436       $term[$i] = $this->createTerm($vocabulary);
       
   437     }
       
   438 
       
   439     // $term[2] is a child of 1 and 5.
       
   440     $term[2]->parent = array($term[1]->tid, $term[5]->tid);
       
   441     taxonomy_term_save($term[2]);
       
   442     // $term[3] is a child of 2.
       
   443     $term[3]->parent = array($term[2]->tid);
       
   444     taxonomy_term_save($term[3]);
       
   445     // $term[5] is a child of 4.
       
   446     $term[5]->parent = array($term[4]->tid);
       
   447     taxonomy_term_save($term[5]);
       
   448 
       
   449     /**
       
   450      * Expected tree:
       
   451      * term[0] | depth: 0
       
   452      * term[1] | depth: 0
       
   453      * -- term[2] | depth: 1
       
   454      * ---- term[3] | depth: 2
       
   455      * term[4] | depth: 0
       
   456      * -- term[5] | depth: 1
       
   457      * ---- term[2] | depth: 2
       
   458      * ------ term[3] | depth: 3
       
   459      */
       
   460     // Count $term[1] parents with $max_depth = 1.
       
   461     $tree = taxonomy_get_tree($vocabulary->vid, $term[1]->tid, 1);
       
   462     $this->assertEqual(1, count($tree), 'We have one parent with depth 1.');
       
   463 
       
   464     // Count all vocabulary tree elements.
       
   465     $tree = taxonomy_get_tree($vocabulary->vid);
       
   466     $this->assertEqual(8, count($tree), 'We have all vocabulary tree elements.');
       
   467 
       
   468     // Count elements in every tree depth.
       
   469     foreach ($tree as $element) {
       
   470       if (!isset($depth_count[$element->depth])) {
       
   471         $depth_count[$element->depth] = 0;
       
   472       }
       
   473       $depth_count[$element->depth]++;
       
   474     }
       
   475     $this->assertEqual(3, $depth_count[0], 'Three elements in taxonomy tree depth 0.');
       
   476     $this->assertEqual(2, $depth_count[1], 'Two elements in taxonomy tree depth 1.');
       
   477     $this->assertEqual(2, $depth_count[2], 'Two elements in taxonomy tree depth 2.');
       
   478     $this->assertEqual(1, $depth_count[3], 'One element in taxonomy tree depth 3.');
       
   479   }
       
   480 
       
   481 }
       
   482 
       
   483 /**
       
   484  * Test for legacy node bug.
       
   485  */
       
   486 class TaxonomyLegacyTestCase extends TaxonomyWebTestCase {
       
   487 
       
   488   public static function getInfo() {
       
   489     return array(
       
   490       'name' => 'Test for legacy node bug.',
       
   491       'description' => 'Posts an article with a taxonomy term and a date prior to 1970.',
       
   492       'group' => 'Taxonomy',
       
   493     );
       
   494   }
       
   495 
       
   496   function setUp() {
       
   497     parent::setUp('taxonomy');
       
   498     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access'));
       
   499     $this->drupalLogin($this->admin_user);
       
   500   }
       
   501 
       
   502   /**
       
   503    * Test taxonomy functionality with nodes prior to 1970.
       
   504    */
       
   505   function testTaxonomyLegacyNode() {
       
   506     // Posts an article with a taxonomy term and a date prior to 1970.
       
   507     $langcode = LANGUAGE_NONE;
       
   508     $edit = array();
       
   509     $edit['title'] = $this->randomName();
       
   510     $edit['date'] = '1969-01-01 00:00:00 -0500';
       
   511     $edit["body[$langcode][0][value]"] = $this->randomName();
       
   512     $edit["field_tags[$langcode]"] = $this->randomName();
       
   513     $this->drupalPost('node/add/article', $edit, t('Save'));
       
   514     // Checks that the node has been saved.
       
   515     $node = $this->drupalGetNodeByTitle($edit['title']);
       
   516     $this->assertEqual($node->created, strtotime($edit['date']), 'Legacy node was saved with the right date.');
       
   517   }
       
   518 
       
   519 }
       
   520 
       
   521 /**
       
   522  * Tests for taxonomy term functions.
       
   523  */
       
   524 class TaxonomyTermTestCase extends TaxonomyWebTestCase {
       
   525 
       
   526   public static function getInfo() {
       
   527     return array(
       
   528       'name' => 'Taxonomy term functions and forms.',
       
   529       'description' => 'Test load, save and delete for taxonomy terms.',
       
   530       'group' => 'Taxonomy',
       
   531     );
       
   532   }
       
   533 
       
   534   function setUp() {
       
   535     parent::setUp('taxonomy');
       
   536     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
       
   537     $this->drupalLogin($this->admin_user);
       
   538     $this->vocabulary = $this->createVocabulary();
       
   539 
       
   540     $field = array(
       
   541       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
   542       'type' => 'taxonomy_term_reference',
       
   543       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
   544       'settings' => array(
       
   545         'allowed_values' => array(
       
   546           array(
       
   547             'vocabulary' => $this->vocabulary->machine_name,
       
   548             'parent' => 0,
       
   549           ),
       
   550         ),
       
   551       ),
       
   552     );
       
   553     field_create_field($field);
       
   554 
       
   555     $this->instance = array(
       
   556       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
   557       'bundle' => 'article',
       
   558       'entity_type' => 'node',
       
   559       'widget' => array(
       
   560         'type' => 'options_select',
       
   561       ),
       
   562       'display' => array(
       
   563         'default' => array(
       
   564           'type' => 'taxonomy_term_reference_link',
       
   565         ),
       
   566       ),
       
   567     );
       
   568     field_create_instance($this->instance);
       
   569   }
       
   570 
       
   571   /**
       
   572    * Test terms in a single and multiple hierarchy.
       
   573    */
       
   574   function testTaxonomyTermHierarchy() {
       
   575     // Create two taxonomy terms.
       
   576     $term1 = $this->createTerm($this->vocabulary);
       
   577     $term2 = $this->createTerm($this->vocabulary);
       
   578 
       
   579     // Check that hierarchy is flat.
       
   580     $vocabulary = taxonomy_vocabulary_load($this->vocabulary->vid);
       
   581     $this->assertEqual(0, $vocabulary->hierarchy, 'Vocabulary is flat.');
       
   582 
       
   583     // Edit $term2, setting $term1 as parent.
       
   584     $edit = array();
       
   585     $edit['parent[]'] = array($term1->tid);
       
   586     $this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
       
   587 
       
   588     // Check the hierarchy.
       
   589     $children = taxonomy_get_children($term1->tid);
       
   590     $parents = taxonomy_get_parents($term2->tid);
       
   591     $this->assertTrue(isset($children[$term2->tid]), 'Child found correctly.');
       
   592     $this->assertTrue(isset($parents[$term1->tid]), 'Parent found correctly.');
       
   593 
       
   594     // Load and save a term, confirming that parents are still set.
       
   595     $term = taxonomy_term_load($term2->tid);
       
   596     taxonomy_term_save($term);
       
   597     $parents = taxonomy_get_parents($term2->tid);
       
   598     $this->assertTrue(isset($parents[$term1->tid]), 'Parent found correctly.');
       
   599 
       
   600     // Create a third term and save this as a parent of term2.
       
   601     $term3 = $this->createTerm($this->vocabulary);
       
   602     $term2->parent = array($term1->tid, $term3->tid);
       
   603     taxonomy_term_save($term2);
       
   604     $parents = taxonomy_get_parents($term2->tid);
       
   605     $this->assertTrue(isset($parents[$term1->tid]) && isset($parents[$term3->tid]), 'Both parents found successfully.');
       
   606   }
       
   607 
       
   608   /**
       
   609    * Test that hook_node_$op implementations work correctly.
       
   610    *
       
   611    * Save & edit a node and assert that taxonomy terms are saved/loaded properly.
       
   612    */
       
   613   function testTaxonomyNode() {
       
   614     // Create two taxonomy terms.
       
   615     $term1 = $this->createTerm($this->vocabulary);
       
   616     $term2 = $this->createTerm($this->vocabulary);
       
   617 
       
   618     // Post an article.
       
   619     $edit = array();
       
   620     $langcode = LANGUAGE_NONE;
       
   621     $edit["title"] = $this->randomName();
       
   622     $edit["body[$langcode][0][value]"] = $this->randomName();
       
   623     $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->tid;
       
   624     $this->drupalPost('node/add/article', $edit, t('Save'));
       
   625 
       
   626     // Check that the term is displayed when the node is viewed.
       
   627     $node = $this->drupalGetNodeByTitle($edit["title"]);
       
   628     $this->drupalGet('node/' . $node->nid);
       
   629     $this->assertText($term1->name, 'Term is displayed when viewing the node.');
       
   630 
       
   631     // Edit the node with a different term.
       
   632     $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->tid;
       
   633     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
       
   634 
       
   635     $this->drupalGet('node/' . $node->nid);
       
   636     $this->assertText($term2->name, 'Term is displayed when viewing the node.');
       
   637 
       
   638     // Preview the node.
       
   639     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Preview'));
       
   640     $this->assertNoUniqueText($term2->name, 'Term is displayed when previewing the node.');
       
   641     $this->drupalPost(NULL, NULL, t('Preview'));
       
   642     $this->assertNoUniqueText($term2->name, 'Term is displayed when previewing the node again.');
       
   643   }
       
   644 
       
   645   /**
       
   646    * Test term creation with a free-tagging vocabulary from the node form.
       
   647    */
       
   648   function testNodeTermCreationAndDeletion() {
       
   649     // Enable tags in the vocabulary.
       
   650     $instance = $this->instance;
       
   651     $instance['widget'] = array('type' => 'taxonomy_autocomplete');
       
   652     $instance['bundle'] = 'page';
       
   653     field_create_instance($instance);
       
   654     $terms = array(
       
   655       'term1' => $this->randomName(),
       
   656       'term2' => $this->randomName() . ', ' . $this->randomName(),
       
   657       'term3' => $this->randomName(),
       
   658     );
       
   659 
       
   660     $edit = array();
       
   661     $langcode = LANGUAGE_NONE;
       
   662     $edit["title"] = $this->randomName();
       
   663     $edit["body[$langcode][0][value]"] = $this->randomName();
       
   664     // Insert the terms in a comma separated list. Vocabulary 1 is a
       
   665     // free-tagging field created by the default profile.
       
   666     $edit[$instance['field_name'] . "[$langcode]"] = drupal_implode_tags($terms);
       
   667 
       
   668     // Preview and verify the terms appear but are not created.
       
   669     $this->drupalPost('node/add/page', $edit, t('Preview'));
       
   670     foreach ($terms as $term) {
       
   671       $this->assertText($term, 'The term appears on the node preview.');
       
   672     }
       
   673     $tree = taxonomy_get_tree($this->vocabulary->vid);
       
   674     $this->assertTrue(empty($tree), 'The terms are not created on preview.');
       
   675 
       
   676     // taxonomy.module does not maintain its static caches.
       
   677     drupal_static_reset();
       
   678 
       
   679     // Save, creating the terms.
       
   680     $this->drupalPost('node/add/page', $edit, t('Save'));
       
   681     $this->assertRaw(t('@type %title has been created.', array('@type' => t('Basic page'), '%title' => $edit["title"])), 'The node was created successfully.');
       
   682     foreach ($terms as $term) {
       
   683       $this->assertText($term, 'The term was saved and appears on the node page.');
       
   684     }
       
   685 
       
   686     // Get the created terms.
       
   687     $term_objects = array();
       
   688     foreach ($terms as $key => $term) {
       
   689       $term_objects[$key] = taxonomy_get_term_by_name($term);
       
   690       $term_objects[$key] = reset($term_objects[$key]);
       
   691     }
       
   692 
       
   693     // Test editing the node.
       
   694     $node = $this->drupalGetNodeByTitle($edit["title"]);
       
   695     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
       
   696     foreach ($terms as $term) {
       
   697       $this->assertText($term, 'The term was retained after edit and still appears on the node page.');
       
   698     }
       
   699 
       
   700     // Delete term 1.
       
   701     $this->drupalPost('taxonomy/term/' . $term_objects['term1']->tid . '/edit', array(), t('Delete'));
       
   702     $this->drupalPost(NULL, NULL, t('Delete'));
       
   703     $term_names = array($term_objects['term2']->name, $term_objects['term3']->name);
       
   704 
       
   705     // Get the node and verify that the terms that should be there still are.
       
   706     $this->drupalGet('node/' . $node->nid);
       
   707     foreach ($term_names as $term_name) {
       
   708       $this->assertText($term_name, format_string('The term %name appears on the node page after one term %deleted was deleted', array('%name' => $term_name, '%deleted' => $term_objects['term1']->name)));
       
   709     }
       
   710     $this->assertNoText($term_objects['term1']->name, format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->name)));
       
   711 
       
   712     // Test autocomplete on term 2, which contains a comma.
       
   713     // The term will be quoted, and the " will be encoded in unicode (\u0022).
       
   714     $input = substr($term_objects['term2']->name, 0, 3);
       
   715     $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input);
       
   716     $this->assertRaw('{"\u0022' . $term_objects['term2']->name . '\u0022":"' . $term_objects['term2']->name . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term2']->name)));
       
   717 
       
   718     // Test autocomplete on term 3 - it is alphanumeric only, so no extra
       
   719     // quoting.
       
   720     $input = substr($term_objects['term3']->name, 0, 3);
       
   721     $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input);
       
   722     $this->assertRaw('{"' . $term_objects['term3']->name . '":"' . $term_objects['term3']->name . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term3']->name)));
       
   723 
       
   724     // Test taxonomy autocomplete with a nonexistent field.
       
   725     $field_name = $this->randomName();
       
   726     $tag = $this->randomName();
       
   727     $message = t("Taxonomy field @field_name not found.", array('@field_name' => $field_name));
       
   728     $this->assertFalse(field_info_field($field_name), format_string('Field %field_name does not exist.', array('%field_name' => $field_name)));
       
   729     $this->drupalGet('taxonomy/autocomplete/' . $field_name . '/' . $tag);
       
   730     $this->assertRaw($message, 'Autocomplete returns correct error message when the taxonomy field does not exist.');
       
   731 
       
   732     // Test the autocomplete path without passing a field_name and terms.
       
   733     // This should not trigger a PHP notice.
       
   734     $field_name = '';
       
   735     $message = t("Taxonomy field @field_name not found.", array('@field_name' => $field_name));
       
   736     $this->drupalGet('taxonomy/autocomplete');
       
   737     $this->assertRaw($message, 'Autocomplete returns correct error message when no taxonomy field is given.');
       
   738   }
       
   739 
       
   740   /**
       
   741    * Tests term autocompletion edge cases with slashes in the names.
       
   742    */
       
   743   function testTermAutocompletion() {
       
   744     // Add a term with a slash in the name.
       
   745     $first_term = $this->createTerm($this->vocabulary);
       
   746     $first_term->name = '10/16/2011';
       
   747     taxonomy_term_save($first_term);
       
   748     // Add another term that differs after the slash character.
       
   749     $second_term = $this->createTerm($this->vocabulary);
       
   750     $second_term->name = '10/17/2011';
       
   751     taxonomy_term_save($second_term);
       
   752     // Add another term that has both a comma and a slash character.
       
   753     $third_term = $this->createTerm($this->vocabulary);
       
   754     $third_term->name = 'term with, a comma and / a slash';
       
   755     taxonomy_term_save($third_term);
       
   756 
       
   757     // Try to autocomplete a term name that matches both terms.
       
   758     // We should get both term in a json encoded string.
       
   759     $input = '10/';
       
   760     $path = 'taxonomy/autocomplete/taxonomy_';
       
   761     $path .= $this->vocabulary->machine_name . '/' . $input;
       
   762     // The result order is not guaranteed, so check each term separately.
       
   763     $url = url($path, array('absolute' => TRUE));
       
   764     $result = drupal_http_request($url);
       
   765     $data = drupal_json_decode($result->data);
       
   766     $this->assertEqual($data[$first_term->name], check_plain($first_term->name), 'Autocomplete returned the first matching term.');
       
   767     $this->assertEqual($data[$second_term->name], check_plain($second_term->name), 'Autocomplete returned the second matching term.');
       
   768 
       
   769     // Try to autocomplete a term name that matches first term.
       
   770     // We should only get the first term in a json encoded string.
       
   771     $input = '10/16';
       
   772     $url = 'taxonomy/autocomplete/taxonomy_';
       
   773     $url .= $this->vocabulary->machine_name . '/' . $input;
       
   774     $this->drupalGet($url);
       
   775     $target = array($first_term->name => check_plain($first_term->name));
       
   776     $this->assertRaw(drupal_json_encode($target), 'Autocomplete returns only the expected matching term.');
       
   777 
       
   778     // Try to autocomplete a term name with both a comma and a slash.
       
   779     $input = '"term with, comma and / a';
       
   780     $url = 'taxonomy/autocomplete/taxonomy_';
       
   781     $url .= $this->vocabulary->machine_name . '/' . $input;
       
   782     $this->drupalGet($url);
       
   783     $n = $third_term->name;
       
   784     // Term names containing commas or quotes must be wrapped in quotes.
       
   785     if (strpos($third_term->name, ',') !== FALSE || strpos($third_term->name, '"') !== FALSE) {
       
   786       $n = '"' . str_replace('"', '""', $third_term->name) . '"';
       
   787     }
       
   788     $target = array($n => check_plain($third_term->name));
       
   789     $this->assertRaw(drupal_json_encode($target), 'Autocomplete returns a term containing a comma and a slash.');
       
   790   }
       
   791 
       
   792   /**
       
   793    * Save, edit and delete a term using the user interface.
       
   794    */
       
   795   function testTermInterface() {
       
   796     $edit = array(
       
   797       'name' => $this->randomName(12),
       
   798       'description[value]' => $this->randomName(100),
       
   799     );
       
   800     // Explicitly set the parents field to 'root', to ensure that
       
   801     // taxonomy_form_term_submit() handles the invalid term ID correctly.
       
   802     $edit['parent[]'] = array(0);
       
   803 
       
   804     // Create the term to edit.
       
   805     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add', $edit, t('Save'));
       
   806 
       
   807     $terms = taxonomy_get_term_by_name($edit['name']);
       
   808     $term = reset($terms);
       
   809     $this->assertNotNull($term, 'Term found in database.');
       
   810 
       
   811     // Submitting a term takes us to the add page; we need the List page.
       
   812     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
       
   813 
       
   814     // Test edit link as accessed from Taxonomy administration pages.
       
   815     // Because Simpletest creates its own database when running tests, we know
       
   816     // the first edit link found on the listing page is to our term.
       
   817     $this->clickLink(t('edit'));
       
   818 
       
   819     $this->assertRaw($edit['name'], 'The randomly generated term name is present.');
       
   820     $this->assertText($edit['description[value]'], 'The randomly generated term description is present.');
       
   821 
       
   822     $edit = array(
       
   823       'name' => $this->randomName(14),
       
   824       'description[value]' => $this->randomName(102),
       
   825     );
       
   826 
       
   827     // Edit the term.
       
   828     $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
       
   829 
       
   830     // Check that the term is still present at admin UI after edit.
       
   831     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
       
   832     $this->assertText($edit['name'], 'The randomly generated term name is present.');
       
   833     $this->assertLink(t('edit'));
       
   834 
       
   835     // View the term and check that it is correct.
       
   836     $this->drupalGet('taxonomy/term/' . $term->tid);
       
   837     $this->assertText($edit['name'], 'The randomly generated term name is present.');
       
   838     $this->assertText($edit['description[value]'], 'The randomly generated term description is present.');
       
   839 
       
   840     // Did this page request display a 'term-listing-heading'?
       
   841     $this->assertPattern('|class="taxonomy-term-description"|', 'Term page displayed the term description element.');
       
   842     // Check that it does NOT show a description when description is blank.
       
   843     $term->description = '';
       
   844     taxonomy_term_save($term);
       
   845     $this->drupalGet('taxonomy/term/' . $term->tid);
       
   846     $this->assertNoPattern('|class="taxonomy-term-description"|', 'Term page did not display the term description when description was blank.');
       
   847 
       
   848     // Check that the term feed page is working.
       
   849     $this->drupalGet('taxonomy/term/' . $term->tid . '/feed');
       
   850 
       
   851     // Check that the term edit page does not try to interpret additional path
       
   852     // components as arguments for taxonomy_form_term().
       
   853     $this->drupalGet('taxonomy/term/' . $term->tid . '/edit/' . $this->randomName());
       
   854 
       
   855     // Delete the term.
       
   856     $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', array(), t('Delete'));
       
   857     $this->drupalPost(NULL, NULL, t('Delete'));
       
   858 
       
   859     // Assert that the term no longer exists.
       
   860     $this->drupalGet('taxonomy/term/' . $term->tid);
       
   861     $this->assertResponse(404, 'The taxonomy term page was not found.');
       
   862   }
       
   863 
       
   864   /**
       
   865    * Save, edit and delete a term using the user interface.
       
   866    */
       
   867   function testTermReorder() {
       
   868     $this->createTerm($this->vocabulary);
       
   869     $this->createTerm($this->vocabulary);
       
   870     $this->createTerm($this->vocabulary);
       
   871 
       
   872     // Fetch the created terms in the default alphabetical order, i.e. term1
       
   873     // precedes term2 alphabetically, and term2 precedes term3.
       
   874     drupal_static_reset('taxonomy_get_tree');
       
   875     drupal_static_reset('taxonomy_get_treeparent');
       
   876     drupal_static_reset('taxonomy_get_treeterms');
       
   877     list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->vid);
       
   878 
       
   879     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
       
   880 
       
   881     // Each term has four hidden fields, "tid:1:0[tid]", "tid:1:0[parent]",
       
   882     // "tid:1:0[depth]", and "tid:1:0[weight]". Change the order to term2,
       
   883     // term3, term1 by setting weight property, make term3 a child of term2 by
       
   884     // setting the parent and depth properties, and update all hidden fields.
       
   885     $edit = array(
       
   886       'tid:' . $term2->tid . ':0[tid]' => $term2->tid,
       
   887       'tid:' . $term2->tid . ':0[parent]' => 0,
       
   888       'tid:' . $term2->tid . ':0[depth]' => 0,
       
   889       'tid:' . $term2->tid . ':0[weight]' => 0,
       
   890       'tid:' . $term3->tid . ':0[tid]' => $term3->tid,
       
   891       'tid:' . $term3->tid . ':0[parent]' => $term2->tid,
       
   892       'tid:' . $term3->tid . ':0[depth]' => 1,
       
   893       'tid:' . $term3->tid . ':0[weight]' => 1,
       
   894       'tid:' . $term1->tid . ':0[tid]' => $term1->tid,
       
   895       'tid:' . $term1->tid . ':0[parent]' => 0,
       
   896       'tid:' . $term1->tid . ':0[depth]' => 0,
       
   897       'tid:' . $term1->tid . ':0[weight]' => 2,
       
   898     );
       
   899     $this->drupalPost(NULL, $edit, t('Save'));
       
   900 
       
   901     drupal_static_reset('taxonomy_get_tree');
       
   902     drupal_static_reset('taxonomy_get_treeparent');
       
   903     drupal_static_reset('taxonomy_get_treeterms');
       
   904     $terms = taxonomy_get_tree($this->vocabulary->vid);
       
   905     $this->assertEqual($terms[0]->tid, $term2->tid, 'Term 2 was moved above term 1.');
       
   906     $this->assertEqual($terms[1]->parents, array($term2->tid), 'Term 3 was made a child of term 2.');
       
   907     $this->assertEqual($terms[2]->tid, $term1->tid, 'Term 1 was moved below term 2.');
       
   908 
       
   909     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name, array(), t('Reset to alphabetical'));
       
   910     // Submit confirmation form.
       
   911     $this->drupalPost(NULL, array(), t('Reset to alphabetical'));
       
   912 
       
   913     drupal_static_reset('taxonomy_get_tree');
       
   914     drupal_static_reset('taxonomy_get_treeparent');
       
   915     drupal_static_reset('taxonomy_get_treeterms');
       
   916     $terms = taxonomy_get_tree($this->vocabulary->vid);
       
   917     $this->assertEqual($terms[0]->tid, $term1->tid, 'Term 1 was moved to back above term 2.');
       
   918     $this->assertEqual($terms[1]->tid, $term2->tid, 'Term 2 was moved to back below term 1.');
       
   919     $this->assertEqual($terms[2]->tid, $term3->tid, 'Term 3 is still below term 2.');
       
   920     $this->assertEqual($terms[2]->parents, array($term2->tid), 'Term 3 is still a child of term 2.' . var_export($terms[1]->tid, 1));
       
   921   }
       
   922 
       
   923   /**
       
   924    * Test saving a term with multiple parents through the UI.
       
   925    */
       
   926   function testTermMultipleParentsInterface() {
       
   927     // Add a new term to the vocabulary so that we can have multiple parents.
       
   928     $parent = $this->createTerm($this->vocabulary);
       
   929 
       
   930     // Add a new term with multiple parents.
       
   931     $edit = array(
       
   932       'name' => $this->randomName(12),
       
   933       'description[value]' => $this->randomName(100),
       
   934       'parent[]' => array(0, $parent->tid),
       
   935     );
       
   936     // Save the new term.
       
   937     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add', $edit, t('Save'));
       
   938 
       
   939     // Check that the term was successfully created.
       
   940     $terms = taxonomy_get_term_by_name($edit['name']);
       
   941     $term = reset($terms);
       
   942     $this->assertNotNull($term, 'Term found in database.');
       
   943     $this->assertEqual($edit['name'], $term->name, 'Term name was successfully saved.');
       
   944     $this->assertEqual($edit['description[value]'], $term->description, 'Term description was successfully saved.');
       
   945     // Check that the parent tid is still there. The other parent (<root>) is
       
   946     // not added by taxonomy_get_parents().
       
   947     $parents = taxonomy_get_parents($term->tid);
       
   948     $parent = reset($parents);
       
   949     $this->assertEqual($edit['parent[]'][1], $parent->tid, 'Term parents were successfully saved.');
       
   950   }
       
   951 
       
   952   /**
       
   953    * Test taxonomy_get_term_by_name().
       
   954    */
       
   955   function testTaxonomyGetTermByName() {
       
   956     $term = $this->createTerm($this->vocabulary);
       
   957 
       
   958     // Load the term with the exact name.
       
   959     $terms = taxonomy_get_term_by_name($term->name);
       
   960     $this->assertTrue(isset($terms[$term->tid]), 'Term loaded using exact name.');
       
   961 
       
   962     // Load the term with space concatenated.
       
   963     $terms  = taxonomy_get_term_by_name('  ' . $term->name . '   ');
       
   964     $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with extra whitespace.');
       
   965 
       
   966     // Load the term with name uppercased.
       
   967     $terms = taxonomy_get_term_by_name(strtoupper($term->name));
       
   968     $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with uppercased name.');
       
   969 
       
   970     // Load the term with name lowercased.
       
   971     $terms = taxonomy_get_term_by_name(strtolower($term->name));
       
   972     $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with lowercased name.');
       
   973 
       
   974     // Try to load an invalid term name.
       
   975     $terms = taxonomy_get_term_by_name('Banana');
       
   976     $this->assertFalse($terms);
       
   977 
       
   978     // Try to load the term using a substring of the name.
       
   979     $terms = taxonomy_get_term_by_name(drupal_substr($term->name, 2));
       
   980     $this->assertFalse($terms);
       
   981 
       
   982     // Create a new term in a different vocabulary with the same name.
       
   983     $new_vocabulary = $this->createVocabulary();
       
   984     $new_term = new stdClass();
       
   985     $new_term->name = $term->name;
       
   986     $new_term->vid = $new_vocabulary->vid;
       
   987     taxonomy_term_save($new_term);
       
   988 
       
   989     // Load multiple terms with the same name.
       
   990     $terms = taxonomy_get_term_by_name($term->name);
       
   991     $this->assertEqual(count($terms), 2, 'Two terms loaded with the same name.');
       
   992 
       
   993     // Load single term when restricted to one vocabulary.
       
   994     $terms = taxonomy_get_term_by_name($term->name, $this->vocabulary->machine_name);
       
   995     $this->assertEqual(count($terms), 1, 'One term loaded when restricted by vocabulary.');
       
   996     $this->assertTrue(isset($terms[$term->tid]), 'Term loaded using exact name and vocabulary machine name.');
       
   997 
       
   998     // Create a new term with another name.
       
   999     $term2 = $this->createTerm($this->vocabulary);
       
  1000 
       
  1001     // Try to load a term by name that doesn't exist in this vocabulary but
       
  1002     // exists in another vocabulary.
       
  1003     $terms = taxonomy_get_term_by_name($term2->name, $new_vocabulary->machine_name);
       
  1004     $this->assertFalse($terms, 'Invalid term name restricted by vocabulary machine name not loaded.');
       
  1005 
       
  1006     // Try to load terms filtering by a non-existing vocabulary.
       
  1007     $terms = taxonomy_get_term_by_name($term2->name, 'non_existing_vocabulary');
       
  1008     $this->assertEqual(count($terms), 0, 'No terms loaded when restricted by a non-existing vocabulary.');
       
  1009   }
       
  1010 
       
  1011 }
       
  1012 
       
  1013 /**
       
  1014  * Tests the rendering of term reference fields in RSS feeds.
       
  1015  */
       
  1016 class TaxonomyRSSTestCase extends TaxonomyWebTestCase {
       
  1017 
       
  1018   public static function getInfo() {
       
  1019     return array(
       
  1020       'name' => 'Taxonomy RSS Content.',
       
  1021       'description' => 'Ensure that data added as terms appears in RSS feeds if "RSS Category" format is selected.',
       
  1022       'group' => 'Taxonomy',
       
  1023     );
       
  1024   }
       
  1025 
       
  1026   function setUp() {
       
  1027     parent::setUp('taxonomy');
       
  1028     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access', 'administer content types', 'administer fields'));
       
  1029     $this->drupalLogin($this->admin_user);
       
  1030     $this->vocabulary = $this->createVocabulary();
       
  1031 
       
  1032     $field = array(
       
  1033       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
  1034       'type' => 'taxonomy_term_reference',
       
  1035       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
  1036       'settings' => array(
       
  1037         'allowed_values' => array(
       
  1038           array(
       
  1039             'vocabulary' => $this->vocabulary->machine_name,
       
  1040             'parent' => 0,
       
  1041           ),
       
  1042         ),
       
  1043       ),
       
  1044     );
       
  1045     field_create_field($field);
       
  1046 
       
  1047     $this->instance = array(
       
  1048       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
  1049       'bundle' => 'article',
       
  1050       'entity_type' => 'node',
       
  1051       'widget' => array(
       
  1052         'type' => 'options_select',
       
  1053       ),
       
  1054       'display' => array(
       
  1055         'default' => array(
       
  1056           'type' => 'taxonomy_term_reference_link',
       
  1057         ),
       
  1058       ),
       
  1059     );
       
  1060     field_create_instance($this->instance);
       
  1061   }
       
  1062 
       
  1063   /**
       
  1064    * Tests that terms added to nodes are displayed in core RSS feed.
       
  1065    *
       
  1066    * Create a node and assert that taxonomy terms appear in rss.xml.
       
  1067    */
       
  1068   function testTaxonomyRSS() {
       
  1069     // Create two taxonomy terms.
       
  1070     $term1 = $this->createTerm($this->vocabulary);
       
  1071 
       
  1072     // RSS display must be added manually.
       
  1073     $this->drupalGet("admin/structure/types/manage/article/display");
       
  1074     $edit = array(
       
  1075       "view_modes_custom[rss]" => '1',
       
  1076     );
       
  1077     $this->drupalPost(NULL, $edit, t('Save'));
       
  1078 
       
  1079     // Change the format to 'RSS category'.
       
  1080     $this->drupalGet("admin/structure/types/manage/article/display/rss");
       
  1081     $edit = array(
       
  1082       "fields[taxonomy_" . $this->vocabulary->machine_name . "][type]" => 'taxonomy_term_reference_rss_category',
       
  1083     );
       
  1084     $this->drupalPost(NULL, $edit, t('Save'));
       
  1085 
       
  1086     // Post an article.
       
  1087     $edit = array();
       
  1088     $langcode = LANGUAGE_NONE;
       
  1089     $edit["title"] = $this->randomName();
       
  1090     $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->tid;
       
  1091     $this->drupalPost('node/add/article', $edit, t('Save'));
       
  1092 
       
  1093     // Check that the term is displayed when the RSS feed is viewed.
       
  1094     $this->drupalGet('rss.xml');
       
  1095     $test_element = array(
       
  1096       'key' => 'category',
       
  1097       'value' => $term1->name,
       
  1098       'attributes' => array(
       
  1099         'domain' => url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE)),
       
  1100       ),
       
  1101     );
       
  1102     $this->assertRaw(format_xml_elements(array($test_element)), 'Term is displayed when viewing the rss feed.');
       
  1103   }
       
  1104 
       
  1105 }
       
  1106 
       
  1107 /**
       
  1108  * Tests the hook implementations that maintain the taxonomy index.
       
  1109  */
       
  1110 class TaxonomyTermIndexTestCase extends TaxonomyWebTestCase {
       
  1111 
       
  1112   public static function getInfo() {
       
  1113     return array(
       
  1114       'name' => 'Taxonomy term index',
       
  1115       'description' => 'Tests the hook implementations that maintain the taxonomy index.',
       
  1116       'group' => 'Taxonomy',
       
  1117     );
       
  1118   }
       
  1119 
       
  1120   function setUp() {
       
  1121     parent::setUp('taxonomy');
       
  1122 
       
  1123     // Create an administrative user.
       
  1124     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
       
  1125     $this->drupalLogin($this->admin_user);
       
  1126 
       
  1127     // Create a vocabulary and add two term reference fields to article nodes.
       
  1128     $this->vocabulary = $this->createVocabulary();
       
  1129 
       
  1130     $this->field_name_1 = drupal_strtolower($this->randomName());
       
  1131     $this->field_1 = array(
       
  1132       'field_name' => $this->field_name_1,
       
  1133       'type' => 'taxonomy_term_reference',
       
  1134       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
  1135       'settings' => array(
       
  1136         'allowed_values' => array(
       
  1137           array(
       
  1138             'vocabulary' => $this->vocabulary->machine_name,
       
  1139             'parent' => 0,
       
  1140           ),
       
  1141         ),
       
  1142       ),
       
  1143     );
       
  1144     field_create_field($this->field_1);
       
  1145     $this->instance_1 = array(
       
  1146       'field_name' => $this->field_name_1,
       
  1147       'bundle' => 'article',
       
  1148       'entity_type' => 'node',
       
  1149       'widget' => array(
       
  1150         'type' => 'options_select',
       
  1151       ),
       
  1152       'display' => array(
       
  1153         'default' => array(
       
  1154           'type' => 'taxonomy_term_reference_link',
       
  1155         ),
       
  1156       ),
       
  1157     );
       
  1158     field_create_instance($this->instance_1);
       
  1159 
       
  1160     $this->field_name_2 = drupal_strtolower($this->randomName());
       
  1161     $this->field_2 = array(
       
  1162       'field_name' => $this->field_name_2,
       
  1163       'type' => 'taxonomy_term_reference',
       
  1164       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
  1165       'settings' => array(
       
  1166         'allowed_values' => array(
       
  1167           array(
       
  1168             'vocabulary' => $this->vocabulary->machine_name,
       
  1169             'parent' => 0,
       
  1170           ),
       
  1171         ),
       
  1172       ),
       
  1173     );
       
  1174     field_create_field($this->field_2);
       
  1175     $this->instance_2 = array(
       
  1176       'field_name' => $this->field_name_2,
       
  1177       'bundle' => 'article',
       
  1178       'entity_type' => 'node',
       
  1179       'widget' => array(
       
  1180         'type' => 'options_select',
       
  1181       ),
       
  1182       'display' => array(
       
  1183         'default' => array(
       
  1184           'type' => 'taxonomy_term_reference_link',
       
  1185         ),
       
  1186       ),
       
  1187     );
       
  1188     field_create_instance($this->instance_2);
       
  1189   }
       
  1190 
       
  1191   /**
       
  1192    * Tests that the taxonomy index is maintained properly.
       
  1193    */
       
  1194   function testTaxonomyIndex() {
       
  1195     // Create terms in the vocabulary.
       
  1196     $term_1 = $this->createTerm($this->vocabulary);
       
  1197     $term_2 = $this->createTerm($this->vocabulary);
       
  1198 
       
  1199     // Post an article.
       
  1200     $edit = array();
       
  1201     $langcode = LANGUAGE_NONE;
       
  1202     $edit["title"] = $this->randomName();
       
  1203     $edit["body[$langcode][0][value]"] = $this->randomName();
       
  1204     $edit["{$this->field_name_1}[$langcode][]"] = $term_1->tid;
       
  1205     $edit["{$this->field_name_2}[$langcode][]"] = $term_1->tid;
       
  1206     $this->drupalPost('node/add/article', $edit, t('Save'));
       
  1207 
       
  1208     // Check that the term is indexed, and only once.
       
  1209     $node = $this->drupalGetNodeByTitle($edit["title"]);
       
  1210     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1211       ':nid' => $node->nid,
       
  1212       ':tid' => $term_1->tid,
       
  1213     ))->fetchField();
       
  1214     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
       
  1215 
       
  1216     // Update the article to change one term.
       
  1217     $edit["{$this->field_name_1}[$langcode][]"] = $term_2->tid;
       
  1218     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
       
  1219 
       
  1220     // Check that both terms are indexed.
       
  1221     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1222       ':nid' => $node->nid,
       
  1223       ':tid' => $term_1->tid,
       
  1224     ))->fetchField();
       
  1225     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
       
  1226     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1227       ':nid' => $node->nid,
       
  1228       ':tid' => $term_2->tid,
       
  1229     ))->fetchField();
       
  1230     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
       
  1231 
       
  1232     // Update the article to change another term.
       
  1233     $edit["{$this->field_name_2}[$langcode][]"] = $term_2->tid;
       
  1234     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
       
  1235 
       
  1236     // Check that only one term is indexed.
       
  1237     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1238       ':nid' => $node->nid,
       
  1239       ':tid' => $term_1->tid,
       
  1240     ))->fetchField();
       
  1241     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
       
  1242     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1243       ':nid' => $node->nid,
       
  1244       ':tid' => $term_2->tid,
       
  1245     ))->fetchField();
       
  1246     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
       
  1247 
       
  1248     // Redo the above tests without interface.
       
  1249     $update_node = array(
       
  1250       'nid' => $node->nid,
       
  1251       'vid' => $node->vid,
       
  1252       'uid' => $node->uid,
       
  1253       'type' => $node->type,
       
  1254       'title' => $this->randomName(),
       
  1255     );
       
  1256 
       
  1257     // Update the article with no term changed.
       
  1258     $updated_node = (object) $update_node;
       
  1259     node_save($updated_node);
       
  1260 
       
  1261     // Check that the index was not changed.
       
  1262     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1263       ':nid' => $node->nid,
       
  1264       ':tid' => $term_1->tid,
       
  1265     ))->fetchField();
       
  1266     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
       
  1267     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1268       ':nid' => $node->nid,
       
  1269       ':tid' => $term_2->tid,
       
  1270     ))->fetchField();
       
  1271     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
       
  1272 
       
  1273     // Update the article to change one term.
       
  1274     $update_node[$this->field_name_1][$langcode] = array(array('tid' => $term_1->tid));
       
  1275     $updated_node = (object) $update_node;
       
  1276     node_save($updated_node);
       
  1277 
       
  1278     // Check that both terms are indexed.
       
  1279     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1280       ':nid' => $node->nid,
       
  1281       ':tid' => $term_1->tid,
       
  1282     ))->fetchField();
       
  1283     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
       
  1284     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1285       ':nid' => $node->nid,
       
  1286       ':tid' => $term_2->tid,
       
  1287     ))->fetchField();
       
  1288     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
       
  1289 
       
  1290     // Update the article to change another term.
       
  1291     $update_node[$this->field_name_2][$langcode] = array(array('tid' => $term_1->tid));
       
  1292     $updated_node = (object) $update_node;
       
  1293     node_save($updated_node);
       
  1294 
       
  1295     // Check that only one term is indexed.
       
  1296     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1297       ':nid' => $node->nid,
       
  1298       ':tid' => $term_1->tid,
       
  1299     ))->fetchField();
       
  1300     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
       
  1301     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       
  1302       ':nid' => $node->nid,
       
  1303       ':tid' => $term_2->tid,
       
  1304     ))->fetchField();
       
  1305     $this->assertEqual(0, $index_count, 'Term 2 is not indexed.');
       
  1306   }
       
  1307 
       
  1308   /**
       
  1309    * Tests that there is a link to the parent term on the child term page.
       
  1310    */
       
  1311   function testTaxonomyTermHierarchyBreadcrumbs() {
       
  1312     // Create two taxonomy terms and set term2 as the parent of term1.
       
  1313     $term1 = $this->createTerm($this->vocabulary);
       
  1314     $term2 = $this->createTerm($this->vocabulary);
       
  1315     $term1->parent = array($term2->tid);
       
  1316     taxonomy_term_save($term1);
       
  1317 
       
  1318     // Verify that the page breadcrumbs include a link to the parent term.
       
  1319     $this->drupalGet('taxonomy/term/' . $term1->tid);
       
  1320     $this->assertRaw(l($term2->name, 'taxonomy/term/' . $term2->tid), 'Parent term link is displayed when viewing the node.');
       
  1321   }
       
  1322 
       
  1323 }
       
  1324 
       
  1325 /**
       
  1326  * Test the taxonomy_term_load_multiple() function.
       
  1327  */
       
  1328 class TaxonomyLoadMultipleTestCase extends TaxonomyWebTestCase {
       
  1329 
       
  1330   public static function getInfo() {
       
  1331     return array(
       
  1332       'name' => 'Taxonomy term multiple loading',
       
  1333       'description' => 'Test the loading of multiple taxonomy terms at once',
       
  1334       'group' => 'Taxonomy',
       
  1335     );
       
  1336   }
       
  1337 
       
  1338   function setUp() {
       
  1339     parent::setUp();
       
  1340     $this->taxonomy_admin = $this->drupalCreateUser(array('administer taxonomy'));
       
  1341     $this->drupalLogin($this->taxonomy_admin);
       
  1342   }
       
  1343 
       
  1344   /**
       
  1345    * Create a vocabulary and some taxonomy terms, ensuring they're loaded
       
  1346    * correctly using taxonomy_term_load_multiple().
       
  1347    */
       
  1348   function testTaxonomyTermMultipleLoad() {
       
  1349     // Create a vocabulary.
       
  1350     $vocabulary = $this->createVocabulary();
       
  1351 
       
  1352     // Create five terms in the vocabulary.
       
  1353     $i = 0;
       
  1354     while ($i < 5) {
       
  1355       $i++;
       
  1356       $this->createTerm($vocabulary);
       
  1357     }
       
  1358     // Load the terms from the vocabulary.
       
  1359     $terms = taxonomy_term_load_multiple(NULL, array('vid' => $vocabulary->vid));
       
  1360     $count = count($terms);
       
  1361     $this->assertEqual($count, 5, format_string('Correct number of terms were loaded. !count terms.', array('!count' => $count)));
       
  1362 
       
  1363     // Load the same terms again by tid.
       
  1364     $terms2 = taxonomy_term_load_multiple(array_keys($terms));
       
  1365     $this->assertEqual($count, count($terms2), 'Five terms were loaded by tid.');
       
  1366     $this->assertEqual($terms, $terms2, 'Both arrays contain the same terms.');
       
  1367 
       
  1368     // Load the terms by tid, with a condition on vid.
       
  1369     $terms3 = taxonomy_term_load_multiple(array_keys($terms2), array('vid' => $vocabulary->vid));
       
  1370     $this->assertEqual($terms2, $terms3);
       
  1371 
       
  1372     // Remove one term from the array, then delete it.
       
  1373     $deleted = array_shift($terms3);
       
  1374     taxonomy_term_delete($deleted->tid);
       
  1375     $deleted_term = taxonomy_term_load($deleted->tid);
       
  1376     $this->assertFalse($deleted_term);
       
  1377 
       
  1378     // Load terms from the vocabulary by vid.
       
  1379     $terms4 = taxonomy_term_load_multiple(NULL, array('vid' => $vocabulary->vid));
       
  1380     $this->assertEqual(count($terms4), 4, 'Correct number of terms were loaded.');
       
  1381     $this->assertFalse(isset($terms4[$deleted->tid]));
       
  1382 
       
  1383     // Create a single term and load it by name.
       
  1384     $term = $this->createTerm($vocabulary);
       
  1385     $loaded_terms = taxonomy_term_load_multiple(array(), array('name' => $term->name));
       
  1386     $this->assertEqual(count($loaded_terms), 1, 'One term was loaded.');
       
  1387     $loaded_term = reset($loaded_terms);
       
  1388     $this->assertEqual($term->tid, $loaded_term->tid, 'Term loaded by name successfully.');
       
  1389   }
       
  1390 }
       
  1391 
       
  1392 /**
       
  1393  * Tests for taxonomy hook invocation.
       
  1394  */
       
  1395 class TaxonomyHooksTestCase extends TaxonomyWebTestCase {
       
  1396   public static function getInfo() {
       
  1397     return array(
       
  1398       'name' => 'Taxonomy term hooks',
       
  1399       'description' => 'Hooks for taxonomy term load/save/delete.',
       
  1400       'group' => 'Taxonomy',
       
  1401     );
       
  1402   }
       
  1403 
       
  1404   function setUp() {
       
  1405     parent::setUp('taxonomy', 'taxonomy_test');
       
  1406     module_load_include('inc', 'taxonomy', 'taxonomy.pages');
       
  1407     $taxonomy_admin = $this->drupalCreateUser(array('administer taxonomy'));
       
  1408     $this->drupalLogin($taxonomy_admin);
       
  1409   }
       
  1410 
       
  1411   /**
       
  1412    * Test that hooks are run correctly on creating, editing, viewing,
       
  1413    * and deleting a term.
       
  1414    *
       
  1415    * @see taxonomy_test.module
       
  1416    */
       
  1417   function testTaxonomyTermHooks() {
       
  1418     $vocabulary = $this->createVocabulary();
       
  1419 
       
  1420     // Create a term with one antonym.
       
  1421     $edit = array(
       
  1422       'name' => $this->randomName(),
       
  1423       'antonym' => 'Long',
       
  1424     );
       
  1425     $this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add', $edit, t('Save'));
       
  1426     $terms = taxonomy_get_term_by_name($edit['name']);
       
  1427     $term = reset($terms);
       
  1428     $this->assertEqual($term->antonym, $edit['antonym'], 'Antonym was loaded into the term object.');
       
  1429 
       
  1430     // Update the term with a different antonym.
       
  1431     $edit = array(
       
  1432       'name' => $this->randomName(),
       
  1433       'antonym' => 'Short',
       
  1434     );
       
  1435     $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
       
  1436     taxonomy_terms_static_reset();
       
  1437     $term = taxonomy_term_load($term->tid);
       
  1438     $this->assertEqual($edit['antonym'], $term->antonym, 'Antonym was successfully edited.');
       
  1439 
       
  1440     // View the term and ensure that hook_taxonomy_term_view() and
       
  1441     // hook_entity_view() are invoked.
       
  1442     $term = taxonomy_term_load($term->tid);
       
  1443     $term_build = taxonomy_term_page($term);
       
  1444     $this->assertFalse(empty($term_build['term_heading']['term']['taxonomy_test_term_view_check']), 'hook_taxonomy_term_view() was invoked when viewing the term.');
       
  1445     $this->assertFalse(empty($term_build['term_heading']['term']['taxonomy_test_entity_view_check']), 'hook_entity_view() was invoked when viewing the term.');
       
  1446 
       
  1447     // Delete the term.
       
  1448     taxonomy_term_delete($term->tid);
       
  1449     $antonym = db_query('SELECT tid FROM {taxonomy_term_antonym} WHERE tid = :tid', array(':tid' => $term->tid))->fetchField();
       
  1450     $this->assertFalse($antonym, 'The antonym were deleted from the database.');
       
  1451   }
       
  1452 
       
  1453 }
       
  1454 
       
  1455 /**
       
  1456  * Tests for taxonomy term field and formatter.
       
  1457  */
       
  1458 class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
       
  1459 
       
  1460   protected $instance;
       
  1461   protected $vocabulary;
       
  1462 
       
  1463   public static function getInfo() {
       
  1464     return array(
       
  1465       'name' => 'Taxonomy term reference field',
       
  1466       'description' => 'Test the creation of term fields.',
       
  1467       'group' => 'Taxonomy',
       
  1468     );
       
  1469   }
       
  1470 
       
  1471   function setUp() {
       
  1472     parent::setUp('field_test');
       
  1473 
       
  1474     $web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer taxonomy'));
       
  1475     $this->drupalLogin($web_user);
       
  1476     $this->vocabulary = $this->createVocabulary();
       
  1477 
       
  1478     // Setup a field and instance.
       
  1479     $this->field_name = drupal_strtolower($this->randomName());
       
  1480     $this->field = array(
       
  1481       'field_name' => $this->field_name,
       
  1482       'type' => 'taxonomy_term_reference',
       
  1483       'settings' => array(
       
  1484         'allowed_values' => array(
       
  1485           array(
       
  1486             'vocabulary' => $this->vocabulary->machine_name,
       
  1487             'parent' => '0',
       
  1488           ),
       
  1489         ),
       
  1490       )
       
  1491     );
       
  1492     field_create_field($this->field);
       
  1493     $this->instance = array(
       
  1494       'field_name' => $this->field_name,
       
  1495       'entity_type' => 'test_entity',
       
  1496       'bundle' => 'test_bundle',
       
  1497       'widget' => array(
       
  1498         'type' => 'options_select',
       
  1499       ),
       
  1500       'display' => array(
       
  1501         'full' => array(
       
  1502           'type' => 'taxonomy_term_reference_link',
       
  1503         ),
       
  1504       ),
       
  1505     );
       
  1506     field_create_instance($this->instance);
       
  1507   }
       
  1508 
       
  1509   /**
       
  1510    * Test term field validation.
       
  1511    */
       
  1512   function testTaxonomyTermFieldValidation() {
       
  1513     // Test valid and invalid values with field_attach_validate().
       
  1514     $langcode = LANGUAGE_NONE;
       
  1515     $entity = field_test_create_stub_entity();
       
  1516     $term = $this->createTerm($this->vocabulary);
       
  1517     $entity->{$this->field_name}[$langcode][0]['tid'] = $term->tid;
       
  1518     try {
       
  1519       field_attach_validate('test_entity', $entity);
       
  1520       $this->pass('Correct term does not cause validation error.');
       
  1521     }
       
  1522     catch (FieldValidationException $e) {
       
  1523       $this->fail('Correct term does not cause validation error.');
       
  1524     }
       
  1525 
       
  1526     $entity = field_test_create_stub_entity();
       
  1527     $bad_term = $this->createTerm($this->createVocabulary());
       
  1528     $entity->{$this->field_name}[$langcode][0]['tid'] = $bad_term->tid;
       
  1529     try {
       
  1530       field_attach_validate('test_entity', $entity);
       
  1531       $this->fail('Wrong term causes validation error.');
       
  1532     }
       
  1533     catch (FieldValidationException $e) {
       
  1534       $this->pass('Wrong term causes validation error.');
       
  1535     }
       
  1536   }
       
  1537 
       
  1538   /**
       
  1539    * Test widgets.
       
  1540    */
       
  1541   function testTaxonomyTermFieldWidgets() {
       
  1542     // Create a term in the vocabulary.
       
  1543     $term = $this->createTerm($this->vocabulary);
       
  1544 
       
  1545     // Display creation form.
       
  1546     $langcode = LANGUAGE_NONE;
       
  1547     $this->drupalGet('test-entity/add/test-bundle');
       
  1548     $this->assertFieldByName("{$this->field_name}[$langcode]", '', 'Widget is displayed.');
       
  1549 
       
  1550     // Submit with some value.
       
  1551     $edit = array(
       
  1552       "{$this->field_name}[$langcode]" => array($term->tid),
       
  1553     );
       
  1554     $this->drupalPost(NULL, $edit, t('Save'));
       
  1555     preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
       
  1556     $id = $match[1];
       
  1557     $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created.');
       
  1558 
       
  1559     // Display the object.
       
  1560     $entity = field_test_entity_test_load($id);
       
  1561     $entities = array($id => $entity);
       
  1562     field_attach_prepare_view('test_entity', $entities, 'full');
       
  1563     $entity->content = field_attach_view('test_entity', $entity, 'full');
       
  1564     $this->content = drupal_render($entity->content);
       
  1565     $this->assertText($term->name, 'Term name is displayed.');
       
  1566 
       
  1567     // Delete the vocabulary and verify that the widget is gone.
       
  1568     taxonomy_vocabulary_delete($this->vocabulary->vid);
       
  1569     $this->drupalGet('test-entity/add/test-bundle');
       
  1570     $this->assertNoFieldByName("{$this->field_name}[$langcode]", '', 'Widget is not displayed.');
       
  1571   }
       
  1572 
       
  1573   /**
       
  1574    * Tests that vocabulary machine name changes are mirrored in field definitions.
       
  1575    */
       
  1576   function testTaxonomyTermFieldChangeMachineName() {
       
  1577     // Add several entries in the 'allowed_values' setting, to make sure that
       
  1578     // they all get updated.
       
  1579     $this->field['settings']['allowed_values'] = array(
       
  1580       array(
       
  1581         'vocabulary' => $this->vocabulary->machine_name,
       
  1582         'parent' => '0',
       
  1583       ),
       
  1584       array(
       
  1585         'vocabulary' => $this->vocabulary->machine_name,
       
  1586         'parent' => '0',
       
  1587       ),
       
  1588       array(
       
  1589         'vocabulary' => 'foo',
       
  1590         'parent' => '0',
       
  1591       ),
       
  1592     );
       
  1593     field_update_field($this->field);
       
  1594     // Change the machine name.
       
  1595     $old_name = $this->vocabulary->machine_name;
       
  1596     $new_name = drupal_strtolower($this->randomName());
       
  1597     $this->vocabulary->machine_name = $new_name;
       
  1598     taxonomy_vocabulary_save($this->vocabulary);
       
  1599 
       
  1600     // Check that entity bundles are properly updated.
       
  1601     $info = entity_get_info('taxonomy_term');
       
  1602     $this->assertFalse(isset($info['bundles'][$old_name]), 'The old bundle name does not appear in entity_get_info().');
       
  1603     $this->assertTrue(isset($info['bundles'][$new_name]), 'The new bundle name appears in entity_get_info().');
       
  1604 
       
  1605     // Check that the field instance is still attached to the vocabulary.
       
  1606     $field = field_info_field($this->field_name);
       
  1607     $allowed_values = $field['settings']['allowed_values'];
       
  1608     $this->assertEqual($allowed_values[0]['vocabulary'], $new_name, 'Index 0: Machine name was updated correctly.');
       
  1609     $this->assertEqual($allowed_values[1]['vocabulary'], $new_name, 'Index 1: Machine name was updated correctly.');
       
  1610     $this->assertEqual($allowed_values[2]['vocabulary'], 'foo', 'Index 2: Machine name was left untouched.');
       
  1611   }
       
  1612 
       
  1613 }
       
  1614 
       
  1615 /**
       
  1616  * Tests a taxonomy term reference field that allows multiple vocabularies.
       
  1617  */
       
  1618 class TaxonomyTermFieldMultipleVocabularyTestCase extends TaxonomyWebTestCase {
       
  1619 
       
  1620   protected $instance;
       
  1621   protected $vocabulary1;
       
  1622   protected $vocabulary2;
       
  1623 
       
  1624   public static function getInfo() {
       
  1625     return array(
       
  1626       'name' => 'Multiple vocabulary term reference field',
       
  1627       'description' => 'Tests term reference fields that allow multiple vocabularies.',
       
  1628       'group' => 'Taxonomy',
       
  1629     );
       
  1630   }
       
  1631 
       
  1632   function setUp() {
       
  1633     parent::setUp('field_test');
       
  1634 
       
  1635     $web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer taxonomy'));
       
  1636     $this->drupalLogin($web_user);
       
  1637     $this->vocabulary1 = $this->createVocabulary();
       
  1638     $this->vocabulary2 = $this->createVocabulary();
       
  1639 
       
  1640     // Set up a field and instance.
       
  1641     $this->field_name = drupal_strtolower($this->randomName());
       
  1642     $this->field = array(
       
  1643       'field_name' => $this->field_name,
       
  1644       'type' => 'taxonomy_term_reference',
       
  1645       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
  1646       'settings' => array(
       
  1647         'allowed_values' => array(
       
  1648           array(
       
  1649             'vocabulary' => $this->vocabulary1->machine_name,
       
  1650             'parent' => '0',
       
  1651           ),
       
  1652           array(
       
  1653             'vocabulary' => $this->vocabulary2->machine_name,
       
  1654             'parent' => '0',
       
  1655           ),
       
  1656         ),
       
  1657       )
       
  1658     );
       
  1659     field_create_field($this->field);
       
  1660     $this->instance = array(
       
  1661       'field_name' => $this->field_name,
       
  1662       'entity_type' => 'test_entity',
       
  1663       'bundle' => 'test_bundle',
       
  1664       'widget' => array(
       
  1665         'type' => 'options_select',
       
  1666       ),
       
  1667       'display' => array(
       
  1668         'full' => array(
       
  1669           'type' => 'taxonomy_term_reference_link',
       
  1670         ),
       
  1671       ),
       
  1672     );
       
  1673     field_create_instance($this->instance);
       
  1674   }
       
  1675 
       
  1676   /**
       
  1677    * Tests term reference field and widget with multiple vocabularies.
       
  1678    */
       
  1679   function testTaxonomyTermFieldMultipleVocabularies() {
       
  1680     // Create a term in each vocabulary.
       
  1681     $term1 = $this->createTerm($this->vocabulary1);
       
  1682     $term2 = $this->createTerm($this->vocabulary2);
       
  1683 
       
  1684     // Submit an entity with both terms.
       
  1685     $langcode = LANGUAGE_NONE;
       
  1686     $this->drupalGet('test-entity/add/test-bundle');
       
  1687     $this->assertFieldByName("{$this->field_name}[$langcode][]", '', 'Widget is displayed.');
       
  1688     $edit = array(
       
  1689       "{$this->field_name}[$langcode][]" => array($term1->tid, $term2->tid),
       
  1690     );
       
  1691     $this->drupalPost(NULL, $edit, t('Save'));
       
  1692     preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
       
  1693     $id = $match[1];
       
  1694     $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created.');
       
  1695 
       
  1696     // Render the entity.
       
  1697     $entity = field_test_entity_test_load($id);
       
  1698     $entities = array($id => $entity);
       
  1699     field_attach_prepare_view('test_entity', $entities, 'full');
       
  1700     $entity->content = field_attach_view('test_entity', $entity, 'full');
       
  1701     $this->content = drupal_render($entity->content);
       
  1702     $this->assertText($term1->name, 'Term 1 name is displayed.');
       
  1703     $this->assertText($term2->name, 'Term 2 name is displayed.');
       
  1704 
       
  1705     // Delete vocabulary 2.
       
  1706     taxonomy_vocabulary_delete($this->vocabulary2->vid);
       
  1707 
       
  1708     // Re-render the content.
       
  1709     $entity = field_test_entity_test_load($id);
       
  1710     $entities = array($id => $entity);
       
  1711     field_attach_prepare_view('test_entity', $entities, 'full');
       
  1712     $entity->content = field_attach_view('test_entity', $entity, 'full');
       
  1713     $this->plainTextContent = FALSE;
       
  1714     $this->content = drupal_render($entity->content);
       
  1715 
       
  1716     // Term 1 should still be displayed; term 2 should not be.
       
  1717     $this->assertText($term1->name, 'Term 1 name is displayed.');
       
  1718     $this->assertNoText($term2->name, 'Term 2 name is not displayed.');
       
  1719 
       
  1720     // Verify that field and instance settings are correct.
       
  1721     $field_info = field_info_field($this->field_name);
       
  1722     $this->assertEqual(sizeof($field_info['settings']['allowed_values']), 1, 'Only one vocabulary is allowed for the field.');
       
  1723 
       
  1724     // The widget should still be displayed.
       
  1725     $this->drupalGet('test-entity/add/test-bundle');
       
  1726     $this->assertFieldByName("{$this->field_name}[$langcode][]", '', 'Widget is still displayed.');
       
  1727 
       
  1728     // Term 1 should still pass validation.
       
  1729     $edit = array(
       
  1730       "{$this->field_name}[$langcode][]" => array($term1->tid),
       
  1731     );
       
  1732     $this->drupalPost(NULL, $edit, t('Save'));
       
  1733   }
       
  1734 
       
  1735 }
       
  1736 
       
  1737 /**
       
  1738  * Test taxonomy token replacement in strings.
       
  1739  */
       
  1740 class TaxonomyTokenReplaceTestCase extends TaxonomyWebTestCase {
       
  1741 
       
  1742   public static function getInfo() {
       
  1743     return array(
       
  1744       'name' => 'Taxonomy token replacement',
       
  1745       'description' => 'Generates text using placeholders for dummy content to check taxonomy token replacement.',
       
  1746       'group' => 'Taxonomy',
       
  1747     );
       
  1748   }
       
  1749 
       
  1750   function setUp() {
       
  1751     parent::setUp();
       
  1752     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
       
  1753     $this->drupalLogin($this->admin_user);
       
  1754     $this->vocabulary = $this->createVocabulary();
       
  1755     $this->langcode = LANGUAGE_NONE;
       
  1756 
       
  1757     $field = array(
       
  1758       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
  1759       'type' => 'taxonomy_term_reference',
       
  1760       'cardinality' => FIELD_CARDINALITY_UNLIMITED,
       
  1761       'settings' => array(
       
  1762         'allowed_values' => array(
       
  1763           array(
       
  1764             'vocabulary' => $this->vocabulary->machine_name,
       
  1765             'parent' => 0,
       
  1766           ),
       
  1767         ),
       
  1768       ),
       
  1769     );
       
  1770     field_create_field($field);
       
  1771 
       
  1772     $this->instance = array(
       
  1773       'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
       
  1774       'bundle' => 'article',
       
  1775       'entity_type' => 'node',
       
  1776       'widget' => array(
       
  1777         'type' => 'options_select',
       
  1778       ),
       
  1779       'display' => array(
       
  1780         'default' => array(
       
  1781           'type' => 'taxonomy_term_reference_link',
       
  1782         ),
       
  1783       ),
       
  1784     );
       
  1785     field_create_instance($this->instance);
       
  1786   }
       
  1787 
       
  1788   /**
       
  1789    * Creates some terms and a node, then tests the tokens generated from them.
       
  1790    */
       
  1791   function testTaxonomyTokenReplacement() {
       
  1792     global $language;
       
  1793 
       
  1794     // Create two taxonomy terms.
       
  1795     $term1 = $this->createTerm($this->vocabulary);
       
  1796     $term2 = $this->createTerm($this->vocabulary);
       
  1797 
       
  1798     // Edit $term2, setting $term1 as parent.
       
  1799     $edit = array();
       
  1800     $edit['name'] = '<blink>Blinking Text</blink>';
       
  1801     $edit['parent[]'] = array($term1->tid);
       
  1802     $this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
       
  1803 
       
  1804     // Create node with term2.
       
  1805     $edit = array();
       
  1806     $node = $this->drupalCreateNode(array('type' => 'article'));
       
  1807     $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term2->tid;
       
  1808     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
       
  1809 
       
  1810     // Generate and test sanitized tokens for term1.
       
  1811     $tests = array();
       
  1812     $tests['[term:tid]'] = $term1->tid;
       
  1813     $tests['[term:name]'] = check_plain($term1->name);
       
  1814     $tests['[term:description]'] = check_markup($term1->description, $term1->format);
       
  1815     $tests['[term:url]'] = url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE));
       
  1816     $tests['[term:node-count]'] = 0;
       
  1817     $tests['[term:parent:name]'] = '[term:parent:name]';
       
  1818     $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name);
       
  1819 
       
  1820     foreach ($tests as $input => $expected) {
       
  1821       $output = token_replace($input, array('term' => $term1), array('language' => $language));
       
  1822       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input)));
       
  1823     }
       
  1824 
       
  1825     // Generate and test sanitized tokens for term2.
       
  1826     $tests = array();
       
  1827     $tests['[term:tid]'] = $term2->tid;
       
  1828     $tests['[term:name]'] = check_plain($term2->name);
       
  1829     $tests['[term:description]'] = check_markup($term2->description, $term2->format);
       
  1830     $tests['[term:url]'] = url('taxonomy/term/' . $term2->tid, array('absolute' => TRUE));
       
  1831     $tests['[term:node-count]'] = 1;
       
  1832     $tests['[term:parent:name]'] = check_plain($term1->name);
       
  1833     $tests['[term:parent:url]'] = url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE));
       
  1834     $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]';
       
  1835     $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name);
       
  1836 
       
  1837     // Test to make sure that we generated something for each token.
       
  1838     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
       
  1839 
       
  1840     foreach ($tests as $input => $expected) {
       
  1841       $output = token_replace($input, array('term' => $term2), array('language' => $language));
       
  1842       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input)));
       
  1843     }
       
  1844 
       
  1845     // Generate and test unsanitized tokens.
       
  1846     $tests['[term:name]'] = $term2->name;
       
  1847     $tests['[term:description]'] = $term2->description;
       
  1848     $tests['[term:parent:name]'] = $term1->name;
       
  1849     $tests['[term:vocabulary:name]'] = $this->vocabulary->name;
       
  1850 
       
  1851     foreach ($tests as $input => $expected) {
       
  1852       $output = token_replace($input, array('term' => $term2), array('language' => $language, 'sanitize' => FALSE));
       
  1853       $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy term token %token replaced.', array('%token' => $input)));
       
  1854     }
       
  1855 
       
  1856     // Generate and test sanitized tokens.
       
  1857     $tests = array();
       
  1858     $tests['[vocabulary:vid]'] = $this->vocabulary->vid;
       
  1859     $tests['[vocabulary:name]'] = check_plain($this->vocabulary->name);
       
  1860     $tests['[vocabulary:description]'] = filter_xss($this->vocabulary->description);
       
  1861     $tests['[vocabulary:node-count]'] = 1;
       
  1862     $tests['[vocabulary:term-count]'] = 2;
       
  1863 
       
  1864     // Test to make sure that we generated something for each token.
       
  1865     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
       
  1866 
       
  1867     foreach ($tests as $input => $expected) {
       
  1868       $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('language' => $language));
       
  1869       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', array('%token' => $input)));
       
  1870     }
       
  1871 
       
  1872     // Generate and test unsanitized tokens.
       
  1873     $tests['[vocabulary:name]'] = $this->vocabulary->name;
       
  1874     $tests['[vocabulary:description]'] = $this->vocabulary->description;
       
  1875 
       
  1876     foreach ($tests as $input => $expected) {
       
  1877       $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('language' => $language, 'sanitize' => FALSE));
       
  1878       $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy vocabulary token %token replaced.', array('%token' => $input)));
       
  1879     }
       
  1880   }
       
  1881 
       
  1882 }
       
  1883 
       
  1884 /**
       
  1885  * Tests for verifying that taxonomy pages use the correct theme.
       
  1886  */
       
  1887 class TaxonomyThemeTestCase extends TaxonomyWebTestCase {
       
  1888 
       
  1889   public static function getInfo() {
       
  1890     return array(
       
  1891       'name' => 'Taxonomy theme switching',
       
  1892       'description' => 'Verifies that various taxonomy pages use the expected theme.',
       
  1893       'group' => 'Taxonomy',
       
  1894     );
       
  1895   }
       
  1896 
       
  1897   function setUp() {
       
  1898     parent::setUp();
       
  1899 
       
  1900     // Make sure we are using distinct default and administrative themes for
       
  1901     // the duration of these tests.
       
  1902     variable_set('theme_default', 'bartik');
       
  1903     variable_set('admin_theme', 'seven');
       
  1904 
       
  1905     // Create and log in as a user who has permission to add and edit taxonomy
       
  1906     // terms and view the administrative theme.
       
  1907     $admin_user = $this->drupalCreateUser(array('administer taxonomy', 'view the administration theme'));
       
  1908     $this->drupalLogin($admin_user);
       
  1909   }
       
  1910 
       
  1911   /**
       
  1912    * Test the theme used when adding, viewing and editing taxonomy terms.
       
  1913    */
       
  1914   function testTaxonomyTermThemes() {
       
  1915     // Adding a term to a vocabulary is considered an administrative action and
       
  1916     // should use the administrative theme.
       
  1917     $vocabulary = $this->createVocabulary();
       
  1918     $this->drupalGet('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add');
       
  1919     $this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page for adding a taxonomy term.");
       
  1920 
       
  1921     // Viewing a taxonomy term should use the default theme.
       
  1922     $term = $this->createTerm($vocabulary);
       
  1923     $this->drupalGet('taxonomy/term/' . $term->tid);
       
  1924     $this->assertRaw('bartik/css/style.css', "The default theme's CSS appears on the page for viewing a taxonomy term.");
       
  1925 
       
  1926     // Editing a taxonomy term should use the same theme as adding one.
       
  1927     $this->drupalGet('taxonomy/term/' . $term->tid . '/edit');
       
  1928     $this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page for editing a taxonomy term.");
       
  1929   }
       
  1930 
       
  1931 }
       
  1932 
       
  1933 /**
       
  1934  * Tests the functionality of EntityFieldQuery for taxonomy entities.
       
  1935  */
       
  1936 class TaxonomyEFQTestCase extends TaxonomyWebTestCase {
       
  1937   public static function getInfo() {
       
  1938     return array(
       
  1939       'name' => 'Taxonomy EntityFieldQuery',
       
  1940       'description' => 'Verifies operation of a taxonomy-based EntityFieldQuery.',
       
  1941       'group' => 'Taxonomy',
       
  1942     );
       
  1943   }
       
  1944 
       
  1945   function setUp() {
       
  1946     parent::setUp();
       
  1947     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy'));
       
  1948     $this->drupalLogin($this->admin_user);
       
  1949     $this->vocabulary = $this->createVocabulary();
       
  1950   }
       
  1951 
       
  1952   /**
       
  1953    * Tests that a basic taxonomy EntityFieldQuery works.
       
  1954    */
       
  1955   function testTaxonomyEFQ() {
       
  1956     $terms = array();
       
  1957     for ($i = 0; $i < 5; $i++) {
       
  1958       $term = $this->createTerm($this->vocabulary);
       
  1959       $terms[$term->tid] = $term;
       
  1960     }
       
  1961     $query = new EntityFieldQuery();
       
  1962     $query->entityCondition('entity_type', 'taxonomy_term');
       
  1963     $result = $query->execute();
       
  1964     $result = $result['taxonomy_term'];
       
  1965     asort($result);
       
  1966     $this->assertEqual(array_keys($terms), array_keys($result), 'Taxonomy terms were retrieved by EntityFieldQuery.');
       
  1967 
       
  1968     // Create a second vocabulary and five more terms.
       
  1969     $vocabulary2 = $this->createVocabulary();
       
  1970     $terms2 = array();
       
  1971     for ($i = 0; $i < 5; $i++) {
       
  1972       $term = $this->createTerm($vocabulary2);
       
  1973       $terms2[$term->tid] = $term;
       
  1974     }
       
  1975 
       
  1976     $query = new EntityFieldQuery();
       
  1977     $query->entityCondition('entity_type', 'taxonomy_term');
       
  1978     $query->entityCondition('bundle', $vocabulary2->machine_name);
       
  1979     $result = $query->execute();
       
  1980     $result = $result['taxonomy_term'];
       
  1981     asort($result);
       
  1982     $this->assertEqual(array_keys($terms2), array_keys($result), format_string('Taxonomy terms from the %name vocabulary were retrieved by EntityFieldQuery.', array('%name' => $vocabulary2->name)));
       
  1983   }
       
  1984 
       
  1985 }
       
  1986 
       
  1987 /**
       
  1988  * Tests that appropriate query tags are added.
       
  1989  */
       
  1990 class TaxonomyQueryAlterTestCase extends TaxonomyWebTestCase {
       
  1991   public static function getInfo() {
       
  1992     return array(
       
  1993       'name' => 'Taxonomy query tags',
       
  1994       'description' => 'Verifies that taxonomy_term_access tags are added to queries.',
       
  1995       'group' => 'Taxonomy',
       
  1996     );
       
  1997   }
       
  1998 
       
  1999   public function setUp() {
       
  2000     parent::setUp('taxonomy_test');
       
  2001   }
       
  2002 
       
  2003   /**
       
  2004    * Tests that appropriate tags are added when querying the database.
       
  2005    */
       
  2006   public function testTaxonomyQueryAlter() {
       
  2007     // Create a new vocabulary and add a few terms to it.
       
  2008     $vocabulary = $this->createVocabulary();
       
  2009     $terms = array();
       
  2010     for ($i = 0; $i < 5; $i++) {
       
  2011       $terms[$i] = $this->createTerm($vocabulary);
       
  2012     }
       
  2013 
       
  2014     // Set up hierarchy. Term 2 is a child of 1.
       
  2015     $terms[2]->parent = array($terms[1]->tid);
       
  2016     taxonomy_term_save($terms[2]);
       
  2017 
       
  2018     $this->setupQueryTagTestHooks();
       
  2019     $loaded_term = taxonomy_term_load($terms[0]->tid);
       
  2020     $this->assertEqual($loaded_term->tid, $terms[0]->tid, 'First term was loaded');
       
  2021     $this->assertQueryTagTestResult(1, 'taxonomy_term_load()');
       
  2022 
       
  2023     $this->setupQueryTagTestHooks();
       
  2024     $loaded_terms = taxonomy_get_tree($vocabulary->vid);
       
  2025     $this->assertEqual(count($loaded_terms), count($terms), 'All terms were loaded');
       
  2026     $this->assertQueryTagTestResult(1, 'taxonomy_get_tree()');
       
  2027 
       
  2028     $this->setupQueryTagTestHooks();
       
  2029     $loaded_terms = taxonomy_get_parents($terms[2]->tid);
       
  2030     $this->assertEqual(count($loaded_terms), 1, 'All parent terms were loaded');
       
  2031     $this->assertQueryTagTestResult(2, 'taxonomy_get_parents()');
       
  2032 
       
  2033     $this->setupQueryTagTestHooks();
       
  2034     $loaded_terms = taxonomy_get_children($terms[1]->tid);
       
  2035     $this->assertEqual(count($loaded_terms), 1, 'All child terms were loaded');
       
  2036     $this->assertQueryTagTestResult(2, 'taxonomy_get_children()');
       
  2037 
       
  2038     $this->setupQueryTagTestHooks();
       
  2039     $query = db_select('taxonomy_term_data', 't');
       
  2040     $query->addField('t', 'tid');
       
  2041     $query->addTag('taxonomy_term_access');
       
  2042     $tids = $query->execute()->fetchCol();
       
  2043     $this->assertEqual(count($tids), count($terms), 'All term IDs were retrieved');
       
  2044     $this->assertQueryTagTestResult(1, 'custom db_select() with taxonomy_term_access tag (preferred)');
       
  2045 
       
  2046     $this->setupQueryTagTestHooks();
       
  2047     $query = db_select('taxonomy_term_data', 't');
       
  2048     $query->addField('t', 'tid');
       
  2049     $query->addTag('term_access');
       
  2050     $tids = $query->execute()->fetchCol();
       
  2051     $this->assertEqual(count($tids), count($terms), 'All term IDs were retrieved');
       
  2052     $this->assertQueryTagTestResult(1, 'custom db_select() with term_access tag (deprecated)');
       
  2053 
       
  2054     $this->setupQueryTagTestHooks();
       
  2055     $query = new EntityFieldQuery();
       
  2056     $query->entityCondition('entity_type', 'taxonomy_term');
       
  2057     $query->addTag('taxonomy_term_access');
       
  2058     $result = $query->execute();
       
  2059     $this->assertEqual(count($result['taxonomy_term']), count($terms), 'All term IDs were retrieved');
       
  2060     $this->assertQueryTagTestResult(1, 'custom EntityFieldQuery with taxonomy_term_access tag (preferred)');
       
  2061 
       
  2062     $this->setupQueryTagTestHooks();
       
  2063     $query = new EntityFieldQuery();
       
  2064     $query->entityCondition('entity_type', 'taxonomy_term');
       
  2065     $query->addTag('term_access');
       
  2066     $result = $query->execute();
       
  2067     $this->assertEqual(count($result['taxonomy_term']), count($terms), 'All term IDs were retrieved');
       
  2068     $this->assertQueryTagTestResult(1, 'custom EntityFieldQuery with term_access tag (deprecated)');
       
  2069   }
       
  2070 
       
  2071   /**
       
  2072    * Sets up the hooks in the test module.
       
  2073    */
       
  2074   protected function setupQueryTagTestHooks() {
       
  2075     taxonomy_terms_static_reset();
       
  2076     variable_set('taxonomy_test_query_alter', 0);
       
  2077     variable_set('taxonomy_test_query_term_access_alter', 0);
       
  2078     variable_set('taxonomy_test_query_taxonomy_term_access_alter', 0);
       
  2079   }
       
  2080 
       
  2081   /**
       
  2082    * Verifies invocation of the hooks in the test module.
       
  2083    *
       
  2084    * @param int $expected_invocations
       
  2085    *   The number of times the hooks are expected to have been invoked.
       
  2086    * @param string $method
       
  2087    *   A string describing the invoked function which generated the query.
       
  2088    */
       
  2089   protected function assertQueryTagTestResult($expected_invocations, $method) {
       
  2090     $this->assertIdentical($expected_invocations, variable_get('taxonomy_test_query_alter'), 'hook_query_alter() invoked when executing ' . $method);
       
  2091     $this->assertIdentical($expected_invocations, variable_get('taxonomy_test_query_term_access_alter'), 'Deprecated hook_query_term_access_alter() invoked when executing ' . $method);
       
  2092     $this->assertIdentical($expected_invocations, variable_get('taxonomy_test_query_taxonomy_term_access_alter'), 'Preferred hook_query_taxonomy_term_access_alter() invoked when executing ' . $method);
       
  2093   }
       
  2094 
       
  2095 }