Newer
Older
<?php
/**
* @file
Dries Buytaert
committed
* Tests for taxonomy.module.
Dries Buytaert
committed
/**
* Class with common helper methods.
*/
Dries Buytaert
committed
class TaxonomyWebTestCase extends DrupalWebTestCase {
/**
* Returns a new vocabulary with random properties.
*/
function createVocabulary() {
// Create a vocabulary.
$vocabulary = new stdClass();
$vocabulary->name = $this->randomName();
$vocabulary->description = $this->randomName();
Dries Buytaert
committed
$vocabulary->machine_name = drupal_strtolower($this->randomName());
Dries Buytaert
committed
$vocabulary->help = '';
$vocabulary->nodes = array('article' => 'article');
$vocabulary->weight = mt_rand(0, 10);
taxonomy_vocabulary_save($vocabulary);
return $vocabulary;
}
/**
* Returns a new term with random properties in vocabulary $vid.
*/
Dries Buytaert
committed
function createTerm($vocabulary) {
Dries Buytaert
committed
$term = new stdClass();
$term->name = $this->randomName();
Dries Buytaert
committed
$term->description = $this->randomName();
Angie Byron
committed
// Use the first available text format.
$term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField();
Dries Buytaert
committed
$term->vid = $vocabulary->vid;
Dries Buytaert
committed
taxonomy_term_save($term);
return $term;
}
}
/**
* Tests for the taxonomy vocabulary interface.
*/
Dries Buytaert
committed
class TaxonomyVocabularyFunctionalTest extends TaxonomyWebTestCase {
Angie Byron
committed
public static function getInfo() {
return array(
'name' => 'Taxonomy vocabulary interface',
'description' => 'Test the taxonomy vocabulary interface.',
'group' => 'Taxonomy',
);
}
function setUp() {
parent::setUp();
$this->admin_user = $this->drupalCreateUser(array('administer taxonomy'));
Dries Buytaert
committed
$this->drupalLogin($this->admin_user);
$this->vocabulary = $this->createVocabulary();
Angie Byron
committed
/**
* Create, edit and delete a vocabulary via the user interface.
Angie Byron
committed
*/
function testVocabularyInterface() {
// Visit the main taxonomy administration page.
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy');
// Create a new vocabulary.
$this->clickLink(t('Add vocabulary'));
$edit = array();
Dries Buytaert
committed
$machine_name = drupal_strtolower($this->randomName());
$edit['name'] = $this->randomName();
$edit['description'] = $this->randomName();
Dries Buytaert
committed
$edit['machine_name'] = $machine_name;
$this->drupalPost(NULL, $edit, t('Save'));
$this->assertRaw(t('Created new vocabulary %name.', array('%name' => $edit['name'])), t('Vocabulary created successfully'));
// Edit the vocabulary.
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy');
$this->assertText($edit['name'], t('Vocabulary found in the vocabulary overview listing.'));
$this->clickLink(t('edit vocabulary'));
$edit = array();
$edit['name'] = $this->randomName();
$this->drupalPost(NULL, $edit, t('Save'));
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy');
$this->assertText($edit['name'], t('Vocabulary found in the vocabulary overview listing.'));
Dries Buytaert
committed
// Try to submit a vocabulary with a duplicate machine name.
Dries Buytaert
committed
$edit['machine_name'] = $machine_name;
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
Dries Buytaert
committed
$this->assertText(t('The machine-readable name is already in use. It must be unique.'));
Dries Buytaert
committed
// Try to submit an invalid machine name.
$edit['machine_name'] = '!&^%';
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
Dries Buytaert
committed
$this->assertText(t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
Dries Buytaert
committed
/**
* Changing weights on the vocabulary overview with two or more vocabularies.
*/
function testTaxonomyAdminChangingWeights() {
// Create some vocabularies.
for ($i = 0; $i < 10; $i++) {
$this->createVocabulary();
}
// Get all vocabularies and change their weights.
$vocabularies = taxonomy_get_vocabularies();
$edit = array();
foreach ($vocabularies as $key => $vocabulary) {
$vocabulary->weight = -$vocabulary->weight;
$vocabularies[$key]->weight = $vocabulary->weight;
$edit[$key . '[weight]'] = $vocabulary->weight;
Dries Buytaert
committed
}
// Saving the new weights via the interface.
Angie Byron
committed
$this->drupalPost('admin/structure/taxonomy', $edit, t('Save'));
Dries Buytaert
committed
// Load the vocabularies from the database.
$new_vocabularies = taxonomy_get_vocabularies();
// Check that the weights are saved in the database correctly.
foreach ($vocabularies as $key => $vocabulary) {
$this->assertEqual($new_vocabularies[$key]->weight, $vocabularies[$key]->weight, t('The vocabulary weight was changed.'));
Dries Buytaert
committed
}
}
/**
* Test the vocabulary overview with no vocabularies.
*/
function testTaxonomyAdminNoVocabularies() {
// Delete all vocabularies.
$vocabularies = taxonomy_get_vocabularies();
foreach ($vocabularies as $key => $vocabulary) {
Dries Buytaert
committed
taxonomy_vocabulary_delete($key);
Dries Buytaert
committed
}
// Confirm that no vocabularies are found in the database.
$this->assertFalse(taxonomy_get_vocabularies(), t('No vocabularies found in the database'));
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy');
Dries Buytaert
committed
// Check the default message for no vocabularies.
$this->assertText(t('No vocabularies available.'), t('No vocabularies were found.'));
Dries Buytaert
committed
}
/**
* Deleting a vocabulary.
*/
function testTaxonomyAdminDeletingVocabulary() {
// Create a vocabulary.
$edit = array(
'name' => $this->randomName(),
Dries Buytaert
committed
'machine_name' => drupal_strtolower($this->randomName()),
Dries Buytaert
committed
);
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
$this->assertText(t('Created new vocabulary'), t('New vocabulary was created.'));
Dries Buytaert
committed
// Check the created vocabulary.
$vocabularies = taxonomy_get_vocabularies();
$vid = $vocabularies[count($vocabularies)-1]->vid;
Dries Buytaert
committed
entity_get_controller('taxonomy_vocabulary')->resetCache();
Dries Buytaert
committed
$vocabulary = taxonomy_vocabulary_load($vid);
$this->assertTrue($vocabulary, t('Vocabulary found in database'));
Dries Buytaert
committed
// Delete the vocabulary.
$edit = array();
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/edit', $edit, t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the vocabulary %name?', array('%name' => $vocabulary->name)), t('[confirm deletion] Asks for confirmation.'));
$this->assertText(t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'), t('[confirm deletion] Inform that all terms will be deleted.'));
Dries Buytaert
committed
// Confirm deletion.
$this->drupalPost(NULL, NULL, t('Delete'));
$this->assertRaw(t('Deleted vocabulary %name.', array('%name' => $vocabulary->name)), t('Vocabulary deleted'));
Dries Buytaert
committed
entity_get_controller('taxonomy_vocabulary')->resetCache();
$this->assertFalse(taxonomy_vocabulary_load($vid), t('Vocabulary is not found in the database'));
Dries Buytaert
committed
}
}
/**
* Tests for taxonomy vocabulary functions.
*/
Dries Buytaert
committed
class TaxonomyVocabularyUnitTest extends TaxonomyWebTestCase {
public static function getInfo() {
return array(
'name' => 'Taxonomy vocabularies',
'description' => 'Test loading, saving and deleting vocabularies.',
'group' => 'Taxonomy',
Angie Byron
committed
function setUp() {
parent::setUp('taxonomy', 'field_test');
$admin_user = $this->drupalCreateUser(array('create article content', 'administer taxonomy'));
Angie Byron
committed
$this->drupalLogin($admin_user);
Dries Buytaert
committed
$this->vocabulary = $this->createVocabulary();
Angie Byron
committed
}
/**
* Ensure that when an invalid vocabulary vid is loaded, it is possible
* to load the same vid successfully if it subsequently becomes valid.
*/
function testTaxonomyVocabularyLoadReturnFalse() {
// Load a vocabulary that doesn't exist.
$vocabularies = taxonomy_get_vocabularies();
$vid = count($vocabularies) + 1;
$vocabulary = taxonomy_vocabulary_load($vid);
// This should not return an object because no such vocabulary exists.
$this->assertTrue(empty($vocabulary), t('No object loaded.'));
Angie Byron
committed
// Create a new vocabulary.
Dries Buytaert
committed
$this->createVocabulary();
Angie Byron
committed
// Load the vocabulary with the same $vid from earlier.
// This should return a vocabulary object since it now matches a real vid.
$vocabulary = taxonomy_vocabulary_load($vid);
$this->assertTrue(!empty($vocabulary) && is_object($vocabulary), t('Vocabulary is an object'));
$this->assertTrue($vocabulary->vid == $vid, t('Valid vocabulary vid is the same as our previously invalid one.'));
Angie Byron
committed
}
Angie Byron
committed
Dries Buytaert
committed
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/**
* Test deleting a taxonomy that contains terms.
*/
function testTaxonomyVocabularyDeleteWithTerms() {
// Delete any existing vocabularies.
foreach (taxonomy_get_vocabularies() as $vocabulary) {
taxonomy_vocabulary_delete($vocabulary->vid);
}
// Assert that there are no terms left.
$this->assertEqual(0, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
// Create a new vocabulary and add a few terms to it.
$vocabulary = $this->createVocabulary();
$terms = array();
for ($i = 0; $i < 5; $i++) {
$terms[$i] = $this->createTerm($vocabulary);
}
// Set up hierarchy. term 2 is a child of 1 and 4 a child of 1 and 2.
$terms[2]->parent = array($terms[1]->tid);
taxonomy_term_save($terms[2]);
$terms[4]->parent = array($terms[1]->tid, $terms[2]->tid);
taxonomy_term_save($terms[4]);
// Assert that there are now 5 terms.
$this->assertEqual(5, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
taxonomy_vocabulary_delete($vocabulary->vid);
// Assert that there are no terms left.
$this->assertEqual(0, db_query('SELECT COUNT(*) FROM {taxonomy_term_data}')->fetchField());
}
Angie Byron
committed
/**
* Ensure that the vocabulary static reset works correctly.
*/
function testTaxonomyVocabularyLoadStaticReset() {
Dries Buytaert
committed
$original_vocabulary = taxonomy_vocabulary_load($this->vocabulary->vid);
$this->assertTrue(is_object($original_vocabulary), t('Vocabulary loaded successfully'));
$this->assertEqual($this->vocabulary->name, $original_vocabulary->name, t('Vocabulary loaded successfully'));
Angie Byron
committed
// Change the name and description.
Dries Buytaert
committed
$vocabulary = $original_vocabulary;
$vocabulary->name = $this->randomName();
$vocabulary->description = $this->randomName();
taxonomy_vocabulary_save($vocabulary);
Angie Byron
committed
Dries Buytaert
committed
// Load the vocabulary.
$new_vocabulary = taxonomy_vocabulary_load($original_vocabulary->vid);
Dries Buytaert
committed
$this->assertEqual($new_vocabulary->name, $vocabulary->name);
$this->assertEqual($new_vocabulary->name, $vocabulary->name);
// Delete the vocabulary.
taxonomy_vocabulary_delete($this->vocabulary->vid);
$vocabularies = taxonomy_get_vocabularies();
$this->assertTrue(!isset($vocabularies[$this->vocabulary->vid]), t('The vocabulary was deleted'));
Angie Byron
committed
}
/**
* Tests for loading multiple vocabularies.
*/
function testTaxonomyVocabularyLoadMultiple() {
// Delete any existing vocabularies.
foreach (taxonomy_get_vocabularies() as $vocabulary) {
taxonomy_vocabulary_delete($vocabulary->vid);
}
// Create some vocabularies and assign weights.
$vocabulary1 = $this->createVocabulary();
$vocabulary1->weight = 0;
taxonomy_vocabulary_save($vocabulary1);
$vocabulary2 = $this->createVocabulary();
$vocabulary2->weight = 1;
taxonomy_vocabulary_save($vocabulary2);
$vocabulary3 = $this->createVocabulary();
$vocabulary3->weight = 2;
taxonomy_vocabulary_save($vocabulary3);
Dries Buytaert
committed
// Fetch the names for all vocabularies, confirm that they are keyed by
// machine name.
$names = taxonomy_vocabulary_get_names();
$this->assertEqual($names[$vocabulary1->machine_name]->name, $vocabulary1->name, t('Vocabulary 1 name found.'));
Dries Buytaert
committed
// Fetch all of the vocabularies using taxonomy_get_vocabularies().
// Confirm that the vocabularies are ordered by weight.
$vocabularies = taxonomy_get_vocabularies();
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, t('Vocabulary was found in the vocabularies array.'));
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, t('Vocabulary was found in the vocabularies array.'));
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, t('Vocabulary was found in the vocabularies array.'));
// Fetch the vocabularies with taxonomy_vocabulary_load_multiple(), specifying IDs.
// Ensure they are returned in the same order as the original array.
$vocabularies = taxonomy_vocabulary_load_multiple(array($vocabulary3->vid, $vocabulary2->vid, $vocabulary1->vid));
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, t('Vocabulary loaded successfully by ID.'));
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, t('Vocabulary loaded successfully by ID.'));
$this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, t('Vocabulary loaded successfully by ID.'));
// Fetch vocabulary 1 by name.
Angie Byron
committed
$vocabulary = current(taxonomy_vocabulary_load_multiple(array(), array('name' => $vocabulary1->name)));
$this->assertTrue($vocabulary->vid == $vocabulary1->vid, t('Vocabulary loaded successfully by name.'));
// Fetch vocabulary 1 by name and ID.
$this->assertTrue(current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('name' => $vocabulary1->name)))->vid == $vocabulary1->vid, t('Vocabulary loaded successfully by name and ID.'));
}
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/**
* Tests that machine name changes are properly reflected.
*/
function testTaxonomyVocabularyChangeMachineName() {
// Add a field instance to the vocabulary.
$field = array(
'field_name' => 'field_test',
'type' => 'test_field',
);
field_create_field($field);
$instance = array(
'field_name' => 'field_test',
'entity_type' => 'taxonomy_term',
'bundle' => $this->vocabulary->machine_name,
);
field_create_instance($instance);
// Change the machine name.
$new_name = drupal_strtolower($this->randomName());
$this->vocabulary->machine_name = $new_name;
taxonomy_vocabulary_save($this->vocabulary);
// Check that the field instance is still attached to the vocabulary.
$this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), t('The bundle name was updated correctly.'));
}
Angie Byron
committed
}
/**
* Unit tests for taxonomy term functions.
*/
class TaxonomyTermUnitTest extends TaxonomyWebTestCase {
Angie Byron
committed
public static function getInfo() {
return array(
'name' => 'Taxonomy term unit tests',
'description' => 'Unit tests for taxonomy term functions.',
'group' => 'Taxonomy',
);
}
function testTermDelete() {
$vocabulary = $this->createVocabulary();
$valid_term = $this->createTerm($vocabulary);
// Delete a valid term.
taxonomy_term_delete($valid_term->tid);
$terms = taxonomy_term_load_multiple(array(), array('vid' => $vocabulary->vid));
$this->assertTrue(empty($terms), 'Vocabulary is empty after deletion');
// Delete an invalid term. Should not throw any notices.
taxonomy_term_delete(42);
}
Angie Byron
committed
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
/**
* Test for legacy node bug.
*/
class TaxonomyLegacyTestCase extends TaxonomyWebTestCase {
public static function getInfo() {
return array(
'name' => 'Test for legacy node bug.',
'description' => 'Posts an article with a taxonomy term and a date prior to 1970.',
'group' => 'Taxonomy',
);
}
function setUp() {
parent::setUp('taxonomy');
$this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access'));
$this->drupalLogin($this->admin_user);
}
/**
* Test taxonomy functionality with nodes prior to 1970.
*/
function testTaxonomyLegacyNode() {
// Posts an article with a taxonomy term and a date prior to 1970.
$langcode = LANGUAGE_NONE;
$edit = array();
$edit['title'] = $this->randomName();
$edit['date'] = '1969-01-01 00:00:00 -0500';
$edit["body[$langcode][0][value]"] = $this->randomName();
$edit["field_tags[$langcode]"] = $this->randomName();
$this->drupalPost('node/add/article', $edit, t('Save'));
// Checks that the node has been saved.
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->assertEqual($node->created, strtotime($edit['date']), t('Legacy node was saved with the right date.'));
}
}
/**
* Tests for taxonomy term functions.
*/
Dries Buytaert
committed
class TaxonomyTermTestCase extends TaxonomyWebTestCase {
Angie Byron
committed
public static function getInfo() {
return array(
'name' => 'Taxonomy term functions and forms.',
'description' => 'Test load, save and delete for taxonomy terms.',
'group' => 'Taxonomy',
);
}
Angie Byron
committed
function setUp() {
parent::setUp('taxonomy');
$this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
Dries Buytaert
committed
$this->drupalLogin($this->admin_user);
$this->vocabulary = $this->createVocabulary();
Angie Byron
committed
Angie Byron
committed
$field = array(
'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
'type' => 'taxonomy_term_reference',
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
'settings' => array(
'allowed_values' => array(
array(
Angie Byron
committed
'vocabulary' => $this->vocabulary->machine_name,
Angie Byron
committed
'parent' => 0,
),
),
),
);
field_create_field($field);
Angie Byron
committed
$this->instance = array(
'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
'bundle' => 'article',
'entity_type' => 'node',
Angie Byron
committed
'widget' => array(
'type' => 'options_select',
),
'display' => array(
Dries Buytaert
committed
'default' => array(
Angie Byron
committed
'type' => 'taxonomy_term_reference_link',
Angie Byron
committed
),
),
);
field_create_instance($this->instance);
}
/**
* Test terms in a single and multiple hierarchy.
*/
function testTaxonomyTermHierarchy() {
// Create two taxonomy terms.
Dries Buytaert
committed
$term1 = $this->createTerm($this->vocabulary);
$term2 = $this->createTerm($this->vocabulary);
// Edit $term2, setting $term1 as parent.
$edit = array();
$edit['parent[]'] = array($term1->tid);
$this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
// Check the hierarchy.
$children = taxonomy_get_children($term1->tid);
$parents = taxonomy_get_parents($term2->tid);
$this->assertTrue(isset($children[$term2->tid]), t('Child found correctly.'));
$this->assertTrue(isset($parents[$term1->tid]), t('Parent found correctly.'));
Dries Buytaert
committed
// Load and save a term, confirming that parents are still set.
$term = taxonomy_term_load($term2->tid);
taxonomy_term_save($term);
$parents = taxonomy_get_parents($term2->tid);
$this->assertTrue(isset($parents[$term1->tid]), t('Parent found correctly.'));
Dries Buytaert
committed
// Create a third term and save this as a parent of term2.
Dries Buytaert
committed
$term3 = $this->createTerm($this->vocabulary);
$term2->parent = array($term1->tid, $term3->tid);
taxonomy_term_save($term2);
$parents = taxonomy_get_parents($term2->tid);
$this->assertTrue(isset($parents[$term1->tid]) && isset($parents[$term3->tid]), t('Both parents found successfully.'));
Angie Byron
committed
}
/**
* Test that hook_node_$op implementations work correctly.
Dries Buytaert
committed
*
* Save & edit a node and assert that taxonomy terms are saved/loaded properly.
*/
function testTaxonomyNode() {
Dries Buytaert
committed
// Create two taxonomy terms.
Dries Buytaert
committed
$term1 = $this->createTerm($this->vocabulary);
$term2 = $this->createTerm($this->vocabulary);
// Post an article.
$edit = array();
$langcode = LANGUAGE_NONE;
$edit["title"] = $this->randomName();
Angie Byron
committed
$edit["body[$langcode][0][value]"] = $this->randomName();
$edit[$this->instance['field_name'] . '[' . $langcode .'][]'] = $term1->tid;
$this->drupalPost('node/add/article', $edit, t('Save'));
// Check that the term is displayed when the node is viewed.
$node = $this->drupalGetNodeByTitle($edit["title"]);
$this->drupalGet('node/' . $node->nid);
$this->assertText($term1->name, t('Term is displayed when viewing the node.'));
// Edit the node with a different term.
Angie Byron
committed
$edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->tid;
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->drupalGet('node/' . $node->nid);
$this->assertText($term2->name, t('Term is displayed when viewing the node.'));
Dries Buytaert
committed
// Preview the node.
Dries Buytaert
committed
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Preview'));
$this->assertNoUniqueText($term2->name, t('Term is displayed when previewing the node.'));
Dries Buytaert
committed
$this->drupalPost(NULL, NULL, t('Preview'));
$this->assertNoUniqueText($term2->name, t('Term is displayed when previewing the node again.'));
Angie Byron
committed
}
/**
* Test term creation with a free-tagging vocabulary from the node form.
*/
Dries Buytaert
committed
function testNodeTermCreationAndDeletion() {
// Enable tags in the vocabulary.
Angie Byron
committed
$instance = $this->instance;
$instance['widget'] = array('type' => 'taxonomy_autocomplete');
$instance['bundle'] = 'page';
field_create_instance($instance);
$terms = array(
$this->randomName(),
$this->randomName(),
$this->randomName(),
);
Angie Byron
committed
$edit = array();
$langcode = LANGUAGE_NONE;
$edit["title"] = $this->randomName();
Angie Byron
committed
$edit["body[$langcode][0][value]"] = $this->randomName();
Angie Byron
committed
// Insert the terms in a comma separated list. Vocabulary 1 is a
// free-tagging field created by the default profile.
Dries Buytaert
committed
$edit[$instance['field_name'] . "[$langcode]"] = implode(', ', $terms);
// Preview and verify the terms appear but are not created.
$this->drupalPost('node/add/page', $edit, t('Preview'));
foreach ($terms as $term) {
$this->assertText($term, t('The term appears on the node preview'));
}
$tree = taxonomy_get_tree($this->vocabulary->vid);
$this->assertTrue(empty($tree), t('The terms are not created on preview.'));
// taxonomy.module does not maintain its static caches.
drupal_static_reset();
// Save, creating the terms.
Angie Byron
committed
$this->drupalPost('node/add/page', $edit, t('Save'));
$this->assertRaw(t('@type %title has been created.', array('@type' => t('Basic page'), '%title' => $edit["title"])), t('The node was created successfully'));
foreach ($terms as $term) {
$this->assertText($term, t('The term was saved and appears on the node page'));
}
Dries Buytaert
committed
// Get the created terms.
list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->vid);
// Delete one term.
$this->drupalPost('taxonomy/term/' . $term1->tid . '/edit', array(), t('Delete'));
$this->drupalPost(NULL, NULL, t('Delete'));
$term_names = array($term2->name, $term3->name);
// Get the node.
$node = $this->drupalGetNodeByTitle($edit["title"]);
$this->drupalGet('node/' . $node->nid);
foreach ($term_names as $term_name) {
$this->assertText($term_name, t('The term %name appears on the node page after one term %deleted was deleted', array('%name' => $term_name, '%deleted' => $term1->name)));
Dries Buytaert
committed
}
$this->assertNoText($term1->name, t('The deleted term %name does not appear on the node page.', array('%name' => $term1->name)));
// Test autocomplete on term 2.
$input = substr($term2->name, 0, 3);
$this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->machine_name . '/' . $input);
$this->assertRaw('{"' . $term2->name . '":"' . $term2->name . '"}', t('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term2->name)));
}
Angie Byron
committed
/**
Angie Byron
committed
* Save, edit and delete a term using the user interface.
Angie Byron
committed
*/
Angie Byron
committed
function testTermInterface() {
Angie Byron
committed
$edit = array(
'name' => $this->randomName(12),
'description[value]' => $this->randomName(100),
Angie Byron
committed
);
// Explicitly set the parents field to 'root', to ensure that
// taxonomy_form_term_submit() handles the invalid term ID correctly.
$edit['parent[]'] = array(0);
Angie Byron
committed
// Create the term to edit.
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add', $edit, t('Save'));
Angie Byron
committed
$terms = taxonomy_get_term_by_name($edit['name']);
$term = reset($terms);
$this->assertNotNull($term, t('Term found in database'));
Angie Byron
committed
// Submitting a term takes us to the add page; we need the List page.
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
Angie Byron
committed
// Test edit link as accessed from Taxonomy administration pages.
// Because Simpletest creates its own database when running tests, we know
// the first edit link found on the listing page is to our term.
$this->clickLink(t('edit'));
Dries Buytaert
committed
$this->assertRaw($edit['name'], t('The randomly generated term name is present.'));
$this->assertText($edit['description[value]'], t('The randomly generated term description is present.'));
Angie Byron
committed
$edit = array(
'name' => $this->randomName(14),
'description[value]' => $this->randomName(102),
Angie Byron
committed
);
// Edit the term.
$this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
Angie Byron
committed
Dries Buytaert
committed
// Check that the term is still present at admin UI after edit.
$this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
$this->assertText($edit['name'], t('The randomly generated term name is present.'));
Dries Buytaert
committed
$this->assertLink(t('edit'));
Angie Byron
committed
// View the term and check that it is correct.
$this->drupalGet('taxonomy/term/' . $term->tid);
$this->assertText($edit['name'], t('The randomly generated term name is present.'));
$this->assertText($edit['description[value]'], t('The randomly generated term description is present.'));
Angie Byron
committed
// Did this page request display a 'term-listing-heading'?
$this->assertPattern('|class="term-listing-heading"|', 'Term page displayed the term description element.');
// Check that it does NOT show a description when description is blank.
$term->description = '';
taxonomy_term_save($term);
$this->drupalGet('taxonomy/term/' . $term->tid);
$this->assertNoPattern('|class="term-listing-heading"|', 'Term page did not display the term description when description was blank.');
Dries Buytaert
committed
// Check that the term feed page is working.
Dries Buytaert
committed
$this->drupalGet('taxonomy/term/' . $term->tid . '/feed');
Angie Byron
committed
// Delete the term.
$this->drupalPost('taxonomy/term/' . $term->tid . '/edit', array(), t('Delete'));
Angie Byron
committed
$this->drupalPost(NULL, NULL, t('Delete'));
// Assert that the term no longer exists.
$this->drupalGet('taxonomy/term/' . $term->tid);
$this->assertResponse(404, t('The taxonomy term page was not found'));
Angie Byron
committed
}
/**
* Save, edit and delete a term using the user interface.
*/
function testTermReorder() {
$this->createTerm($this->vocabulary);
$this->createTerm($this->vocabulary);
$this->createTerm($this->vocabulary);
// Fetch the created terms in the default alphabetical order, i.e. term1
// precedes term2 alphabetically, and term2 precedes term3.
drupal_static_reset('taxonomy_get_tree');
drupal_static_reset('taxonomy_get_treeparent');
drupal_static_reset('taxonomy_get_treeterms');
list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->vid);
Dries Buytaert
committed
$this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name);
Angie Byron
committed
// Each term has four hidden fields, "tid:1:0[tid]", "tid:1:0[parent]",
// "tid:1:0[depth]", and "tid:1:0[weight]". Change the order to term2,
// term3, term1 by setting weight property, make term3 a child of term2 by
// setting the parent and depth properties, and update all hidden fields.
$edit = array(
'tid:' . $term2->tid . ':0[tid]' => $term2->tid,
'tid:' . $term2->tid . ':0[parent]' => 0,
'tid:' . $term2->tid . ':0[depth]' => 0,
Angie Byron
committed
'tid:' . $term2->tid . ':0[weight]' => 0,
'tid:' . $term3->tid . ':0[tid]' => $term3->tid,
'tid:' . $term3->tid . ':0[parent]' => $term2->tid,
'tid:' . $term3->tid . ':0[depth]' => 1,
Angie Byron
committed
'tid:' . $term3->tid . ':0[weight]' => 1,
'tid:' . $term1->tid . ':0[tid]' => $term1->tid,
'tid:' . $term1->tid . ':0[parent]' => 0,
'tid:' . $term1->tid . ':0[depth]' => 0,
Angie Byron
committed
'tid:' . $term1->tid . ':0[weight]' => 2,
);
$this->drupalPost(NULL, $edit, t('Save'));
drupal_static_reset('taxonomy_get_tree');
drupal_static_reset('taxonomy_get_treeparent');
drupal_static_reset('taxonomy_get_treeterms');
$terms = taxonomy_get_tree($this->vocabulary->vid);
$this->assertEqual($terms[0]->tid, $term2->tid, t('Term 2 was moved above term 1.'));
$this->assertEqual($terms[1]->parents, array($term2->tid), t('Term 3 was made a child of term 2.'));
$this->assertEqual($terms[2]->tid, $term1->tid, t('Term 1 was moved below term 2.'));
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name, array(), t('Reset to alphabetical'));
// Submit confirmation form.
$this->drupalPost(NULL, array(), t('Reset to alphabetical'));
drupal_static_reset('taxonomy_get_tree');
drupal_static_reset('taxonomy_get_treeparent');
drupal_static_reset('taxonomy_get_treeterms');
$terms = taxonomy_get_tree($this->vocabulary->vid);
$this->assertEqual($terms[0]->tid, $term1->tid, t('Term 1 was moved to back above term 2.'));
$this->assertEqual($terms[1]->tid, $term2->tid, t('Term 2 was moved to back below term 1.'));
$this->assertEqual($terms[2]->tid, $term3->tid, t('Term 3 is still below term 2.'));
$this->assertEqual($terms[2]->parents, array($term2->tid), t('Term 3 is still a child of term 2.').var_export($terms[1]->tid,1));
/**
* Test taxonomy_get_term_by_name().
*/
function testTaxonomyGetTermByName() {
Dries Buytaert
committed
$term = $this->createTerm($this->vocabulary);
// Load the term with the exact name.
$terms = taxonomy_get_term_by_name($term->name);
$this->assertTrue(isset($terms[$term->tid]), t('Term loaded using exact name.'));
// Load the term with space concatenated.
$terms = taxonomy_get_term_by_name(' ' . $term->name . ' ');
$this->assertTrue(isset($terms[$term->tid]), t('Term loaded with extra whitespace.'));
// Load the term with name uppercased.
$terms = taxonomy_get_term_by_name(strtoupper($term->name));
$this->assertTrue(isset($terms[$term->tid]), t('Term loaded with uppercased name.'));
// Load the term with name lowercased.
$terms = taxonomy_get_term_by_name(strtolower($term->name));
$this->assertTrue(isset($terms[$term->tid]), t('Term loaded with lowercased name.'));
// Try to load an invalid term name.
$terms = taxonomy_get_term_by_name('Banana');
$this->assertFalse($terms);
// Try to load the term using a substring of the name.
$terms = taxonomy_get_term_by_name(drupal_substr($term->name, 2));
$this->assertFalse($terms);
}
/**
* Test the taxonomy_term_load_multiple() function.
*/
class TaxonomyLoadMultipleUnitTest extends TaxonomyWebTestCase {
Angie Byron
committed
public static function getInfo() {
return array(
'name' => 'Taxonomy term multiple loading',
'description' => 'Test the loading of multiple taxonomy terms at once',
'group' => 'Taxonomy',
);
}
function setUp() {
parent::setUp();
$this->taxonomy_admin = $this->drupalCreateUser(array('administer taxonomy'));
$this->drupalLogin($this->taxonomy_admin);
}
/**
* Create a vocabulary and some taxonomy terms, ensuring they're loaded
* correctly using taxonomy_term_load_multiple().
*/
function testTaxonomyTermMultipleLoad() {
// Create a vocabulary.
$vocabulary = $this->createVocabulary();
// Create five terms in the vocabulary.
$i = 0;
while ($i < 5) {
$i++;
Dries Buytaert
committed
$this->createTerm($vocabulary);
}
// Load the terms from the vocabulary.
$terms = taxonomy_term_load_multiple(NULL, array('vid' => $vocabulary->vid));
$count = count($terms);
$this->assertTrue($count == 5, t('Correct number of terms were loaded. !count terms.', array('!count' => $count)));
// Load the same terms again by tid.
$terms2 = taxonomy_term_load_multiple(array_keys($terms));
$this->assertTrue($count == count($terms2), t('Five terms were loaded by tid'));
$this->assertEqual($terms, $terms2, t('Both arrays contain the same terms'));
// Load the terms by tid, with a condition on vid.
$terms3 = taxonomy_term_load_multiple(array_keys($terms2), array('vid' => $vocabulary->vid));
$this->assertEqual($terms2, $terms3);
// Remove one term from the array, then delete it.
$deleted = array_shift($terms3);
taxonomy_term_delete($deleted->tid);
Dries Buytaert
committed
$deleted_term = taxonomy_term_load($deleted->tid);
$this->assertFalse($deleted_term);
// Load terms from the vocabulary by vid.
Dries Buytaert
committed
$terms4 = taxonomy_term_load_multiple(NULL, array('vid' => $vocabulary->vid));
$this->assertTrue(count($terms4 == 4), t('Correct number of terms were loaded.'));
$this->assertFalse(isset($terms4[$deleted->tid]));
Dries Buytaert
committed
// Create a single term and load it by name.
Dries Buytaert
committed
$term = $this->createTerm($vocabulary);
Dries Buytaert
committed
$loaded_terms = taxonomy_term_load_multiple(array(), array('name' => $term->name));
$this->assertEqual(count($loaded_terms), 1, t('One term was loaded'));
Dries Buytaert
committed
$loaded_term = reset($loaded_terms);
$this->assertEqual($term->tid, $loaded_term->tid, t('Term loaded by name successfully.'));
}
}
/**
* Tests for taxonomy hook invocation.
*/
Dries Buytaert
committed
class TaxonomyHooksTestCase extends TaxonomyWebTestCase {
Angie Byron
committed
public static function getInfo() {
'name' => 'Taxonomy term hooks',
'description' => 'Hooks for taxonomy term load/save/delete.',
'group' => 'Taxonomy',
);
}
function setUp() {
parent::setUp('taxonomy', 'taxonomy_test');
$taxonomy_admin = $this->drupalCreateUser(array('administer taxonomy'));
$this->drupalLogin($taxonomy_admin);
}
/**
* Test that hooks are run correctly on creating, editing and deleting a term.
*/
function testTaxonomyTermHooks() {
Dries Buytaert
committed
$vocabulary = $this->createVocabulary();
// Create a term with one antonym.
$edit = array(
'name' => $this->randomName(),
'antonym' => 'Long',
Dries Buytaert
committed
$this->drupalPost('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add', $edit, t('Save'));
$terms = taxonomy_get_term_by_name($edit['name']);
$term = reset($terms);
$this->assertEqual($term->antonym, $edit['antonym'], t('Antonym was loaded into the term object'));
// Update the term with a different antonym.
$edit = array(
'name' => $this->randomName(),
'antonym' => 'Short',
);
$this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
Dries Buytaert
committed
taxonomy_terms_static_reset();
$term = taxonomy_term_load($term->tid);
$this->assertEqual($edit['antonym'], $term->antonym, t('Antonym was successfully edited'));
// Delete the term.
taxonomy_term_delete($term->tid);
$antonym = db_query('SELECT tid FROM {taxonomy_term_antonym} WHERE tid = :tid', array(':tid' => $term->tid))->fetchField();
$this->assertFalse($antonym, t('The antonym were deleted from the database.'));
Dries Buytaert
committed
/**
* Tests for taxonomy term field and formatter.
*/
class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
protected $instance;
protected $vocabulary;
public static function getInfo() {
return array(
Angie Byron
committed
'name' => 'Taxonomy term reference field',
'description' => 'Test the creation of term fields.',
'group' => 'Taxonomy',
Dries Buytaert
committed
);
}
function setUp() {
parent::setUp('field_test');
$web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer taxonomy'));
$this->drupalLogin($web_user);
$this->vocabulary = $this->createVocabulary();
// Setup a field and instance.
Dries Buytaert
committed
$this->field_name = drupal_strtolower($this->randomName());
$this->field = array(
'field_name' => $this->field_name,
Angie Byron
committed
'type' => 'taxonomy_term_reference',
Dries Buytaert
committed
'settings' => array(
'allowed_values' => array(
array(
Angie Byron
committed
'vocabulary' => $this->vocabulary->machine_name,
Dries Buytaert
committed
'parent' => '0',
),
),
)
);
field_create_field($this->field);
$this->instance = array(
'field_name' => $this->field_name,
'entity_type' => 'test_entity',
'bundle' => 'test_bundle',
Dries Buytaert
committed
'widget' => array(
'type' => 'options_select',
),
'display' => array(
'full' => array(
Angie Byron
committed
'type' => 'taxonomy_term_reference_link',
Dries Buytaert
committed
),
),
);
field_create_instance($this->instance);
Dries Buytaert
committed
/**
* Test term field validation.
*/
function testTaxonomyTermFieldValidation() {
Dries Buytaert
committed
// Test valid and invalid values with field_attach_validate().
$langcode = LANGUAGE_NONE;
$entity = field_test_create_stub_entity();
Dries Buytaert
committed
$term = $this->createTerm($this->vocabulary);
Dries Buytaert
committed
$entity->{$this->field_name}[$langcode][0]['tid'] = $term->tid;
Dries Buytaert
committed
try {
Dries Buytaert
committed
field_attach_validate('test_entity', $entity);
$this->pass(t('Correct term does not cause validation error'));
Dries Buytaert
committed
}
catch (FieldValidationException $e) {
$this->fail(t('Correct term does not cause validation error'));
Dries Buytaert
committed
}
$entity = field_test_create_stub_entity();
Dries Buytaert
committed
$bad_term = $this->createTerm($this->createVocabulary());
Dries Buytaert
committed
$entity->{$this->field_name}[$langcode][0]['tid'] = $bad_term->tid;
Dries Buytaert
committed
try {
field_attach_validate('test_entity', $entity);
$this->fail(t('Wrong term causes validation error'));
Dries Buytaert
committed
}
catch (FieldValidationException $e) {
$this->pass(t('Wrong term causes validation error'));
Dries Buytaert
committed
}
}
/**
* Test widgets.
*/
function testTaxonomyTermFieldWidgets() {
// Create a term in the vocabulary.
$term = $this->createTerm($this->vocabulary);
// Display creation form.
$langcode = LANGUAGE_NONE;
Dries Buytaert
committed
$this->drupalGet('test-entity/add/test-bundle');
$this->assertFieldByName("{$this->field_name}[$langcode]", '', t('Widget is displayed'));
Dries Buytaert
committed
// Submit with some value.
$edit = array(
Angie Byron
committed
"{$this->field_name}[$langcode]" => array($term->tid),
Dries Buytaert
committed
);
$this->drupalPost(NULL, $edit, t('Save'));
Dries Buytaert
committed
preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
Dries Buytaert
committed
$id = $match[1];
$this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), t('Entity was created'));
Dries Buytaert
committed
// Display the object.
$entity = field_test_entity_test_load($id);
$entities = array($id => $entity);
field_attach_prepare_view('test_entity', $entities, 'full');
$entity->content = field_attach_view('test_entity', $entity, 'full');
Dries Buytaert
committed
$this->content = drupal_render($entity->content);
$this->assertText($term->name, t('Term name is displayed'));
Dries Buytaert
committed
}
/**
* Tests that vocabulary machine name changes are mirrored in field definitions.
*/
function testTaxonomyTermFieldChangeMachineName() {
// Add several entries in the 'allowed_values' setting, to make sure that
// they all get updated.
$this->field['settings']['allowed_values'] = array(
array(
'vocabulary' => $this->vocabulary->machine_name,
'parent' => '0',