TermTest.php 25.4 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\taxonomy\Tests;

5
use Drupal\Component\Utility\Tags;
6
use Drupal\Component\Utility\Unicode;
7
use Drupal\Core\Field\FieldStorageDefinitionInterface;
8
use Drupal\field\Entity\FieldConfig;
9
use Drupal\taxonomy\Entity\Term;
10
use Drupal\taxonomy\Entity\Vocabulary;
11

12
/**
13 14 15
 * Tests load, save and delete for taxonomy terms.
 *
 * @group taxonomy
16 17 18
 */
class TermTest extends TaxonomyTestBase {

19 20 21 22 23 24 25 26 27 28 29 30 31 32
  /**
   * Vocabulary for testing.
   *
   * @var \Drupal\taxonomy\VocabularyInterface
   */
  protected $vocabulary;

  /**
   * Taxonomy term reference field for testing.
   *
   * @var \Drupal\field\FieldConfigInterface
   */
  protected $field;

33 34 35 36 37 38 39 40 41 42
  /**
   * Modules to enable.
   *
   * @var string[]
   */
  public static $modules = ['block'];

  /**
   * {@inheritdoc}
   */
43
  protected function setUp() {
44
    parent::setUp();
45 46 47

    $this->drupalPlaceBlock('local_actions_block');
    $this->drupalPlaceBlock('local_tasks_block');
48
    $this->drupalPlaceBlock('page_title_block');
49

50
    $this->drupalLogin($this->drupalCreateUser(['administer taxonomy', 'bypass node access']));
51 52
    $this->vocabulary = $this->createVocabulary();

53
    $field_name = 'taxonomy_' . $this->vocabulary->id();
54 55 56 57

    $handler_settings = array(
      'target_bundles' => array(
        $this->vocabulary->id() => $this->vocabulary->id(),
58
      ),
59 60 61 62
      'auto_create' => TRUE,
    );
    $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
    $this->field = FieldConfig::loadByName('node', 'article', $field_name);
63

64
    entity_get_form_display('node', 'article', 'default')
65
      ->setComponent($field_name, array(
66 67 68
        'type' => 'options_select',
      ))
      ->save();
69
    entity_get_display('node', 'article', 'default')
70
      ->setComponent($field_name, array(
71
        'type' => 'entity_reference_label',
72 73
      ))
      ->save();
74 75 76 77 78 79 80 81 82 83
  }

  /**
   * Test terms in a single and multiple hierarchy.
   */
  function testTaxonomyTermHierarchy() {
    // Create two taxonomy terms.
    $term1 = $this->createTerm($this->vocabulary);
    $term2 = $this->createTerm($this->vocabulary);

84 85 86
    // Get the taxonomy storage.
    $taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term');

87
    // Check that hierarchy is flat.
88
    $vocabulary = Vocabulary::load($this->vocabulary->id());
89
    $this->assertEqual(0, $vocabulary->getHierarchy(), 'Vocabulary is flat.');
90 91 92

    // Edit $term2, setting $term1 as parent.
    $edit = array();
93
    $edit['parent[]'] = array($term1->id());
94
    $this->drupalPostForm('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save'));
95 96

    // Check the hierarchy.
97 98
    $children = $taxonomy_storage->loadChildren($term1->id());
    $parents = $taxonomy_storage->loadParents($term2->id());
99 100
    $this->assertTrue(isset($children[$term2->id()]), 'Child found correctly.');
    $this->assertTrue(isset($parents[$term1->id()]), 'Parent found correctly.');
101 102

    // Load and save a term, confirming that parents are still set.
103
    $term = Term::load($term2->id());
104
    $term->save();
105
    $parents = $taxonomy_storage->loadParents($term2->id());
106
    $this->assertTrue(isset($parents[$term1->id()]), 'Parent found correctly.');
107 108 109

    // Create a third term and save this as a parent of term2.
    $term3 = $this->createTerm($this->vocabulary);
110
    $term2->parent = array($term1->id(), $term3->id());
111
    $term2->save();
112
    $parents = $taxonomy_storage->loadParents($term2->id());
113
    $this->assertTrue(isset($parents[$term1->id()]) && isset($parents[$term3->id()]), 'Both parents found successfully.');
114 115
  }

116 117 118 119 120
  /**
   * Tests that many terms with parents show on each page
   */
  function testTaxonomyTermChildTerms() {
    // Set limit to 10 terms per page. Set variable to 9 so 10 terms appear.
121
    $this->config('taxonomy.settings')->set('terms_per_page_admin', '9')->save();
122 123 124
    $term1 = $this->createTerm($this->vocabulary);
    $terms_array = '';

125 126
    $taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term');

127 128 129 130 131 132 133 134 135 136 137 138
    // Create 40 terms. Terms 1-12 get parent of $term1. All others are
    // individual terms.
    for ($x = 1; $x <= 40; $x++) {
      $edit = array();
      // Set terms in order so we know which terms will be on which pages.
      $edit['weight'] = $x;

      // Set terms 1-20 to be children of first term created.
      if ($x <= 12) {
        $edit['parent'] = $term1->id();
      }
      $term = $this->createTerm($this->vocabulary, $edit);
139 140
      $children = $taxonomy_storage->loadChildren($term1->id());
      $parents = $taxonomy_storage->loadParents($term->id());
141
      $terms_array[$x] = Term::load($term->id());
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
    }

    // Get Page 1.
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
    $this->assertText($term1->getName(), 'Parent Term is displayed on Page 1');
    for ($x = 1; $x <= 13; $x++) {
      $this->assertText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' found on Page 1');
    }

    // Get Page 2.
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array('query' => array('page' => 1)));
    $this->assertText($term1->getName(), 'Parent Term is displayed on Page 2');
    for ($x = 1; $x <= 18; $x++) {
      $this->assertText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' found on Page 2');
    }

    // Get Page 3.
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array('query' => array('page' => 2)));
    $this->assertNoText($term1->getName(), 'Parent Term is not displayed on Page 3');
    for ($x = 1; $x <= 17; $x++) {
      $this->assertNoText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' not found on Page 3');
    }
164
    for ($x = 18; $x <= 25; $x++) {
165 166 167 168
      $this->assertText($terms_array[$x]->getName(), $terms_array[$x]->getName() . ' found on Page 3');
    }
  }

169 170 171 172 173 174 175 176 177 178 179 180
  /**
   * Test that hook_node_$op implementations work correctly.
   *
   * Save & edit a node and assert that taxonomy terms are saved/loaded properly.
   */
  function testTaxonomyNode() {
    // Create two taxonomy terms.
    $term1 = $this->createTerm($this->vocabulary);
    $term2 = $this->createTerm($this->vocabulary);

    // Post an article.
    $edit = array();
181 182
    $edit['title[0][value]'] = $this->randomMachineName();
    $edit['body[0][value]'] = $this->randomMachineName();
183
    $edit[$this->field->getName() . '[]'] = $term1->id();
184
    $this->drupalPostForm('node/add/article', $edit, t('Save'));
185 186

    // Check that the term is displayed when the node is viewed.
187
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
188
    $this->drupalGet('node/' . $node->id());
189
    $this->assertText($term1->getName(), 'Term is displayed when viewing the node.');
190

191
    $this->clickLink(t('Edit'));
192
    $this->assertText($term1->getName(), 'Term is displayed when editing the node.');
193
    $this->drupalPostForm(NULL, array(), t('Save'));
194
    $this->assertText($term1->getName(), 'Term is displayed after saving the node with no changes.');
195

196
    // Edit the node with a different term.
197
    $edit[$this->field->getName() . '[]'] = $term2->id();
198
    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
199

200
    $this->drupalGet('node/' . $node->id());
201
    $this->assertText($term2->getName(), 'Term is displayed when viewing the node.');
202 203

    // Preview the node.
204
    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
205 206 207
    $this->assertUniqueText($term2->getName(), 'Term is displayed when previewing the node.');
    $this->drupalPostForm('node/' . $node->id() . '/edit', NULL, t('Preview'));
    $this->assertUniqueText($term2->getName(), 'Term is displayed when previewing the node again.');
208 209 210 211 212 213 214
  }

  /**
   * Test term creation with a free-tagging vocabulary from the node form.
   */
  function testNodeTermCreationAndDeletion() {
    // Enable tags in the vocabulary.
215
    $field = $this->field;
216
    entity_get_form_display($field->getTargetEntityTypeId(), $field->getTargetBundle(), 'default')
217
      ->setComponent($field->getName(), array(
218
        'type' => 'entity_reference_autocomplete_tags',
219 220 221 222 223
        'settings' => array(
          'placeholder' => 'Start typing here.',
        ),
      ))
      ->save();
224 225 226
    // Prefix the terms with a letter to ensure there is no clash in the first
    // three letters.
    // @see https://www.drupal.org/node/2397691
227
    $terms = array(
228 229 230 231
      'term1' => 'a' . $this->randomMachineName(),
      'term2' => 'b' . $this->randomMachineName(),
      'term3' => 'c' . $this->randomMachineName() . ', ' . $this->randomMachineName(),
      'term4' => 'd' . $this->randomMachineName(),
232 233 234
    );

    $edit = array();
235 236
    $edit['title[0][value]'] = $this->randomMachineName();
    $edit['body[0][value]'] = $this->randomMachineName();
237 238
    // Insert the terms in a comma separated list. Vocabulary 1 is a
    // free-tagging field created by the default profile.
239
    $edit[$field->getName() . '[target_id]'] = Tags::implode($terms);
240

241 242
    // Verify the placeholder is there.
    $this->drupalGet('node/add/article');
243
    $this->assertRaw('placeholder="Start typing here."', 'Placeholder is present.');
244

245
    // Preview and verify the terms appear but are not created.
246
    $this->drupalPostForm(NULL, $edit, t('Preview'));
247
    foreach ($terms as $term) {
248
      $this->assertText($term, 'The term appears on the node preview.');
249
    }
250
    $tree = $this->container->get('entity.manager')->getStorage('taxonomy_term')->loadTree($this->vocabulary->id());
251 252 253 254 255 256
    $this->assertTrue(empty($tree), 'The terms are not created on preview.');

    // taxonomy.module does not maintain its static caches.
    taxonomy_terms_static_reset();

    // Save, creating the terms.
257
    $this->drupalPostForm('node/add/article', $edit, t('Save'));
258
    $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title[0][value]'])), 'The node was created successfully.');
259 260 261 262 263 264 265 266 267 268 269
    foreach ($terms as $term) {
      $this->assertText($term, 'The term was saved and appears on the node page.');
    }

    // Get the created terms.
    $term_objects = array();
    foreach ($terms as $key => $term) {
      $term_objects[$key] = taxonomy_term_load_multiple_by_name($term);
      $term_objects[$key] = reset($term_objects[$key]);
    }

270 271 272 273 274 275 276 277 278
    // Get the node.
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);

    // Test editing the node.
    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
    foreach ($terms as $term) {
      $this->assertText($term, 'The term was retained after edit and still appears on the node page.');
    }

279
    // Delete term 1 from the term edit page.
280 281
    $this->drupalGet('taxonomy/term/' . $term_objects['term1']->id() . '/edit');
    $this->clickLink(t('Delete'));
282
    $this->drupalPostForm(NULL, NULL, t('Delete'));
283 284

    // Delete term 2 from the term delete page.
285 286
    $this->drupalGet('taxonomy/term/' . $term_objects['term2']->id() . '/delete');
    $this->drupalPostForm(NULL, array(), t('Delete'));
287
    $term_names = array($term_objects['term3']->getName(), $term_objects['term4']->getName());
288

289
    $this->drupalGet('node/' . $node->id());
290 291

    foreach ($term_names as $term_name) {
292
      $this->assertText($term_name, format_string('The term %name appears on the node page after two terms, %deleted1 and %deleted2, were deleted.', array('%name' => $term_name, '%deleted1' => $term_objects['term1']->getName(), '%deleted2' => $term_objects['term2']->getName())));
293
    }
294 295
    $this->assertNoText($term_objects['term1']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->getName())));
    $this->assertNoText($term_objects['term2']->getName(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term2']->getName())));
296 297 298 299 300 301
  }

  /**
   * Save, edit and delete a term using the user interface.
   */
  function testTermInterface() {
302
    \Drupal::service('module_installer')->install(array('views'));
303
    $edit = array(
304 305
      'name[0][value]' => $this->randomMachineName(12),
      'description[0][value]' => $this->randomMachineName(100),
306 307
    );
    // Explicitly set the parents field to 'root', to ensure that
308
    // TermForm::save() handles the invalid term ID correctly.
309 310 311
    $edit['parent[]'] = array(0);

    // Create the term to edit.
312
    $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save'));
313

314
    $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']);
315 316 317 318
    $term = reset($terms);
    $this->assertNotNull($term, 'Term found in database.');

    // Submitting a term takes us to the add page; we need the List page.
319
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
320

321
    $this->clickLink(t('Edit'));
322

323 324
    $this->assertRaw($edit['name[0][value]'], 'The randomly generated term name is present.');
    $this->assertText($edit['description[0][value]'], 'The randomly generated term description is present.');
325 326

    $edit = array(
327 328
      'name[0][value]' => $this->randomMachineName(14),
      'description[0][value]' => $this->randomMachineName(102),
329 330 331
    );

    // Edit the term.
332
    $this->drupalPostForm('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save'));
333 334

    // Check that the term is still present at admin UI after edit.
335
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
336
    $this->assertText($edit['name[0][value]'], 'The randomly generated term name is present.');
337
    $this->assertLink(t('Edit'));
338

339
    // Check the term link can be clicked through to the term page.
340
    $this->clickLink($edit['name[0][value]']);
341 342
    $this->assertResponse(200, 'Term page can be accessed via the listing link.');

343
    // View the term and check that it is correct.
344
    $this->drupalGet('taxonomy/term/' . $term->id());
345 346
    $this->assertText($edit['name[0][value]'], 'The randomly generated term name is present.');
    $this->assertText($edit['description[0][value]'], 'The randomly generated term description is present.');
347 348

    // Did this page request display a 'term-listing-heading'?
349
    $this->assertTrue($this->xpath('//div[contains(@class, "field--name-description")]'), 'Term page displayed the term description element.');
350
    // Check that it does NOT show a description when description is blank.
351
    $term->setDescription(NULL);
352
    $term->save();
353
    $this->drupalGet('taxonomy/term/' . $term->id());
354
    $this->assertFalse($this->xpath('//div[contains(@class, "field--entity-taxonomy-term--description")]'), 'Term page did not display the term description when description was blank.');
355

356
    // Check that the description value is processed.
357
    $value = $this->randomMachineName();
358
    $term->setDescription($value);
359 360 361
    $term->save();
    $this->assertEqual($term->description->processed, "<p>$value</p>\n");

362
    // Check that the term feed page is working.
363
    $this->drupalGet('taxonomy/term/' . $term->id() . '/feed');
364 365

    // Delete the term.
366 367
    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
    $this->clickLink(t('Delete'));
368
    $this->drupalPostForm(NULL, NULL, t('Delete'));
369 370

    // Assert that the term no longer exists.
371
    $this->drupalGet('taxonomy/term/' . $term->id());
372 373 374 375 376 377 378 379 380 381 382
    $this->assertResponse(404, 'The taxonomy term page was not found.');
  }

  /**
   * Save, edit and delete a term using the user interface.
   */
  function testTermReorder() {
    $this->createTerm($this->vocabulary);
    $this->createTerm($this->vocabulary);
    $this->createTerm($this->vocabulary);

383 384
    $taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term');

385 386
    // Fetch the created terms in the default alphabetical order, i.e. term1
    // precedes term2 alphabetically, and term2 precedes term3.
387 388
    $taxonomy_storage->resetCache();
    list($term1, $term2, $term3) = $taxonomy_storage->loadTree($this->vocabulary->id(), 0, NULL, TRUE);
389

390
    $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
391 392 393 394 395 396

    // Each term has four hidden fields, "tid:1:0[tid]", "tid:1:0[parent]",
    // "tid:1:0[depth]", and "tid:1:0[weight]". Change the order to term2,
    // term3, term1 by setting weight property, make term3 a child of term2 by
    // setting the parent and depth properties, and update all hidden fields.
    $edit = array(
397 398 399 400 401 402 403 404 405 406 407 408
      'terms[tid:' . $term2->id() . ':0][term][tid]' => $term2->id(),
      'terms[tid:' . $term2->id() . ':0][term][parent]' => 0,
      'terms[tid:' . $term2->id() . ':0][term][depth]' => 0,
      'terms[tid:' . $term2->id() . ':0][weight]' => 0,
      'terms[tid:' . $term3->id() . ':0][term][tid]' => $term3->id(),
      'terms[tid:' . $term3->id() . ':0][term][parent]' => $term2->id(),
      'terms[tid:' . $term3->id() . ':0][term][depth]' => 1,
      'terms[tid:' . $term3->id() . ':0][weight]' => 1,
      'terms[tid:' . $term1->id() . ':0][term][tid]' => $term1->id(),
      'terms[tid:' . $term1->id() . ':0][term][parent]' => 0,
      'terms[tid:' . $term1->id() . ':0][term][depth]' => 0,
      'terms[tid:' . $term1->id() . ':0][weight]' => 2,
409
    );
410
    $this->drupalPostForm(NULL, $edit, t('Save'));
411

412 413
    $taxonomy_storage->resetCache();
    $terms = $taxonomy_storage->loadTree($this->vocabulary->id());
414 415 416
    $this->assertEqual($terms[0]->tid, $term2->id(), 'Term 2 was moved above term 1.');
    $this->assertEqual($terms[1]->parents, array($term2->id()), 'Term 3 was made a child of term 2.');
    $this->assertEqual($terms[2]->tid, $term1->id(), 'Term 1 was moved below term 2.');
417

418
    $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview', array(), t('Reset to alphabetical'));
419
    // Submit confirmation form.
420
    $this->drupalPostForm(NULL, array(), t('Reset to alphabetical'));
421 422
    // Ensure form redirected back to overview.
    $this->assertUrl('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview');
423

424 425
    $taxonomy_storage->resetCache();
    $terms = $taxonomy_storage->loadTree($this->vocabulary->id(), 0, NULL, TRUE);
426 427 428
    $this->assertEqual($terms[0]->id(), $term1->id(), 'Term 1 was moved to back above term 2.');
    $this->assertEqual($terms[1]->id(), $term2->id(), 'Term 2 was moved to back below term 1.');
    $this->assertEqual($terms[2]->id(), $term3->id(), 'Term 3 is still below term 2.');
429
    $this->assertEqual($terms[2]->parents, array($term2->id()), 'Term 3 is still a child of term 2.');
430 431 432 433 434 435 436 437 438 439 440
  }

  /**
   * Test saving a term with multiple parents through the UI.
   */
  function testTermMultipleParentsInterface() {
    // Add a new term to the vocabulary so that we can have multiple parents.
    $parent = $this->createTerm($this->vocabulary);

    // Add a new term with multiple parents.
    $edit = array(
441 442
      'name[0][value]' => $this->randomMachineName(12),
      'description[0][value]' => $this->randomMachineName(100),
443
      'parent[]' => array(0, $parent->id()),
444 445
    );
    // Save the new term.
446
    $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save'));
447 448

    // Check that the term was successfully created.
449
    $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']);
450 451
    $term = reset($terms);
    $this->assertNotNull($term, 'Term found in database.');
452 453
    $this->assertEqual($edit['name[0][value]'], $term->getName(), 'Term name was successfully saved.');
    $this->assertEqual($edit['description[0][value]'], $term->getDescription(), 'Term description was successfully saved.');
454
    // Check that the parent tid is still there. The other parent (<root>) is
455 456
    // not added by \Drupal\taxonomy\TermStorageInterface::loadParents().
    $parents = $this->container->get('entity.manager')->getStorage('taxonomy_term')->loadParents($term->id());
457
    $parent = reset($parents);
458
    $this->assertEqual($edit['parent[]'][1], $parent->id(), 'Term parents were successfully saved.');
459 460 461 462 463 464 465 466 467
  }

  /**
   * Test taxonomy_term_load_multiple_by_name().
   */
  function testTaxonomyGetTermByName() {
    $term = $this->createTerm($this->vocabulary);

    // Load the term with the exact name.
468
    $terms = taxonomy_term_load_multiple_by_name($term->getName());
469
    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded using exact name.');
470 471

    // Load the term with space concatenated.
472
    $terms = taxonomy_term_load_multiple_by_name('  ' . $term->getName() . '   ');
473
    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with extra whitespace.');
474 475

    // Load the term with name uppercased.
476
    $terms = taxonomy_term_load_multiple_by_name(strtoupper($term->getName()));
477
    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with uppercased name.');
478 479

    // Load the term with name lowercased.
480
    $terms = taxonomy_term_load_multiple_by_name(strtolower($term->getName()));
481
    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with lowercased name.');
482 483 484

    // Try to load an invalid term name.
    $terms = taxonomy_term_load_multiple_by_name('Banana');
485
    $this->assertFalse($terms, 'No term loaded with an invalid name.');
486 487

    // Try to load the term using a substring of the name.
488
    $terms = taxonomy_term_load_multiple_by_name(Unicode::substr($term->getName(), 2), 'No term loaded with a substring of the name.');
489 490 491 492
    $this->assertFalse($terms);

    // Create a new term in a different vocabulary with the same name.
    $new_vocabulary = $this->createVocabulary();
493
    $new_term = Term::create([
494
      'name' => $term->getName(),
495
      'vid' => $new_vocabulary->id(),
496
    ]);
497
    $new_term->save();
498 499

    // Load multiple terms with the same name.
500
    $terms = taxonomy_term_load_multiple_by_name($term->getName());
501 502 503
    $this->assertEqual(count($terms), 2, 'Two terms loaded with the same name.');

    // Load single term when restricted to one vocabulary.
504
    $terms = taxonomy_term_load_multiple_by_name($term->getName(), $this->vocabulary->id());
505
    $this->assertEqual(count($terms), 1, 'One term loaded when restricted by vocabulary.');
506
    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded using exact name and vocabulary machine name.');
507 508 509 510 511 512

    // Create a new term with another name.
    $term2 = $this->createTerm($this->vocabulary);

    // Try to load a term by name that doesn't exist in this vocabulary but
    // exists in another vocabulary.
513
    $terms = taxonomy_term_load_multiple_by_name($term2->getName(), $new_vocabulary->id());
514 515 516
    $this->assertFalse($terms, 'Invalid term name restricted by vocabulary machine name not loaded.');

    // Try to load terms filtering by a non-existing vocabulary.
517
    $terms = taxonomy_term_load_multiple_by_name($term2->getName(), 'non_existing_vocabulary');
518 519
    $this->assertEqual(count($terms), 0, 'No terms loaded when restricted by a non-existing vocabulary.');
  }
520 521 522 523 524 525

  /**
   * Tests that editing and saving a node with no changes works correctly.
   */
  function testReSavingTags() {
    // Enable tags in the vocabulary.
526
    $field = $this->field;
527
    entity_get_form_display($field->getTargetEntityTypeId(), $field->getTargetBundle(), 'default')
528
      ->setComponent($field->getName(), array(
529
        'type' => 'entity_reference_autocomplete_tags',
530 531
      ))
      ->save();
532 533 534 535

    // Create a term and a node using it.
    $term = $this->createTerm($this->vocabulary);
    $edit = array();
536 537
    $edit['title[0][value]'] = $this->randomMachineName(8);
    $edit['body[0][value]'] = $this->randomMachineName(16);
538
    $edit[$this->field->getName() . '[target_id]'] = $term->getName();
539
    $this->drupalPostForm('node/add/article', $edit, t('Save'));
540 541 542 543

    // Check that the term is displayed when editing and saving the node with no
    // changes.
    $this->clickLink(t('Edit'));
544
    $this->assertRaw($term->getName(), 'Term is displayed when editing the node.');
545
    $this->drupalPostForm(NULL, array(), t('Save'));
546
    $this->assertRaw($term->getName(), 'Term is displayed after saving the node with no changes.');
547 548
  }

549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
  /**
   * Check the breadcrumb on edit and delete a term page.
   */
  public function testTermBreadcrumbs() {
    $edit = [
      'name[0][value]' => $this->randomMachineName(14),
      'description[0][value]' => $this->randomMachineName(100),
      'parent[]' => [0],
    ];

    // Create the term.
    $this->drupalPostForm('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/add', $edit, t('Save'));

    $terms = taxonomy_term_load_multiple_by_name($edit['name[0][value]']);
    $term = reset($terms);
    $this->assertNotNull($term, 'Term found in database.');

    // Check the breadcrumb on the term edit page.
    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
    $breadcrumbs = $this->cssSelect('nav.breadcrumb ol li a');
    $this->assertIdentical(count($breadcrumbs), 2, 'The breadcrumbs are present on the page.');
    $this->assertIdentical((string) $breadcrumbs[0], 'Home', 'First breadcrumb text is Home');
    $this->assertIdentical((string) $breadcrumbs[1], $term->label(), 'Second breadcrumb text is term name on term edit page.');
    $this->assertEscaped((string) $breadcrumbs[1], 'breadcrumbs displayed and escaped.');

    // Check the breadcrumb on the term delete page.
    $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
    $breadcrumbs = $this->cssSelect('nav.breadcrumb ol li a');
    $this->assertIdentical(count($breadcrumbs), 2, 'The breadcrumbs are present on the page.');
    $this->assertIdentical((string) $breadcrumbs[0], 'Home', 'First breadcrumb text is Home');
    $this->assertIdentical((string) $breadcrumbs[1], $term->label(), 'Second breadcrumb text is term name on term delete page.');
    $this->assertEscaped((string) $breadcrumbs[1], 'breadcrumbs displayed and escaped.');
  }

583
}