|
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'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 } |