outline-8.x-1.x-dev/tests/src/Functional/EntryTest.php

tests/src/Functional/EntryTest.php
<?php

namespace Drupal\Tests\outline\Functional;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\outline\Entity\Entry;

/**
 * Tests load, save and delete for outline entries.
 *
 * @group outline
 */
class EntryTest extends OutlineTestBase {

  /**
   * Outline for testing.
   *
   * @var \Drupal\outline\OutlineInterface
   */
  protected $outline;

  /**
   * Outline entry reference field for testing.
   *
   * @var \Drupal\field\FieldConfigInterface
   */
  protected $field;

  /**
   * Modules to enable.
   *
   * @var string[]
   */
  protected static $modules = ['block'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'classy';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

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

    $this->drupalLogin($this->drupalCreateUser([
      'administer outline',
      'bypass node access',
    ]));
    $this->outline = $this->createOutline();

    $field_name = 'outline_' . $this->outline->id();

    $handler_settings = [
      'target_bundles' => [
        $this->outline->id() => $this->outline->id(),
      ],
      'auto_create' => TRUE,
    ];
    $this->createEntityReferenceField('node', 'article', $field_name, NULL, 'outline_entry', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
    $this->field = FieldConfig::loadByName('node', 'article', $field_name);

    /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
    $display_repository = \Drupal::service('entity_display.repository');
    $display_repository->getFormDisplay('node', 'article')
      ->setComponent($field_name, [
        'type' => 'options_select',
      ])
      ->save();
    $display_repository->getViewDisplay('node', 'article')
      ->setComponent($field_name, [
        'type' => 'entity_reference_label',
      ])
      ->save();
  }

  /**
   * The "parent" field must restrict references to the same outline.
   */
  public function testParentHandlerSettings() {
    $outline_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('outline_entry', $this->outline->id());
    $parent_target_bundles = $outline_fields['parent']->getSetting('handler_settings')['target_bundles'];
    $this->assertIdentical([$this->outline->id() => $this->outline->id()], $parent_target_bundles);
  }

  /**
   * Test entries in a single and multiple hierarchy.
   */
  public function testOutlineEntryHierarchy() {
    // Create two outline entries.
    $entry1 = $this->createEntry($this->outline);
    $entry2 = $this->createEntry($this->outline);

    // Get the outline storage.
    /** @var \Drupal\outline\EntryStorageInterface $outline_storage */
    $outline_storage = $this->container->get('entity_type.manager')->getStorage('outline_entry');

    // Check that hierarchy is flat.
    $this->assertEquals(0, $outline_storage->getOutlineHierarchyType($this->outline->id()), 'Outline is flat.');

    // Edit $entry2, setting $entry1 as parent.
    $edit = [];
    $edit['parent[]'] = [$entry1->id()];
    $this->drupalPostForm('outline/entry/' . $entry2->id() . '/edit', $edit, t('Save'));

    // Check the hierarchy.
    $children = $outline_storage->loadChildren($entry1->id());
    $parents = $outline_storage->loadParents($entry2->id());
    $this->assertTrue(isset($children[$entry2->id()]), 'Child found correctly.');
    $this->assertTrue(isset($parents[$entry1->id()]), 'Parent found correctly.');

    // Load and save a entry, confirming that parents are still set.
    $entry = Entry::load($entry2->id());
    $entry->save();
    $parents = $outline_storage->loadParents($entry2->id());
    $this->assertTrue(isset($parents[$entry1->id()]), 'Parent found correctly.');

    // Create a third entry and save this as a parent of entry2.
    $entry3 = $this->createEntry($this->outline);
    $entry2->parent = [$entry1->id(), $entry3->id()];
    $entry2->save();
    $parents = $outline_storage->loadParents($entry2->id());
    $this->assertTrue(isset($parents[$entry1->id()]) && isset($parents[$entry3->id()]), 'Both parents found successfully.');
  }

  /**
   * Tests that many entries with parents show on each page
   */
  public function testOutlineEntryChildEntrys() {
    // Set limit to 10 entries per page. Set variable to 9 so 10 entries appear.
    $this->config('outline.settings')->set('entries_per_page_admin', '9')->save();
    $entry1 = $this->createEntry($this->outline);
    $entries_array = [];

    $outline_storage = $this->container->get('entity_type.manager')->getStorage('outline_entry');

    // Create 40 entries. Entrys 1-12 get parent of $entry1. All others are
    // individual entries.
    for ($x = 1; $x <= 40; $x++) {
      $edit = [];
      // Set entries in order so we know which entries will be on which pages.
      $edit['weight'] = $x;

      // Set entries 1-20 to be children of first entry created.
      if ($x <= 12) {
        $edit['parent'] = $entry1->id();
      }
      $entry = $this->createEntry($this->outline, $edit);
      $children = $outline_storage->loadChildren($entry1->id());
      $parents = $outline_storage->loadParents($entry->id());
      $entries_array[$x] = Entry::load($entry->id());
    }

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

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

    // Get Page 3.
    $this->drupalGet('admin/structure/outline/manage/' . $this->outline->id() . '/overview', ['query' => ['page' => 2]]);
    $this->assertNoText($entry1->getName(), 'Parent Entry is not displayed on Page 3');
    for ($x = 1; $x <= 17; $x++) {
      $this->assertNoText($entries_array[$x]->getName(), $entries_array[$x]->getName() . ' not found on Page 3');
    }
    for ($x = 18; $x <= 25; $x++) {
      $this->assertText($entries_array[$x]->getName(), $entries_array[$x]->getName() . ' found on Page 3');
    }
  }

  /**
   * Test that hook_node_$op implementations work correctly.
   *
   * Save & edit a node and assert that outline entries are saved/loaded properly.
   */
  public function testOutlineNode() {
    // Create two outline entries.
    $entry1 = $this->createEntry($this->outline);
    $entry2 = $this->createEntry($this->outline);

    // Post an article.
    $edit = [];
    $edit['title[0][value]'] = $this->randomMachineName();
    $edit['body[0][value]'] = $this->randomMachineName();
    $edit[$this->field->getName() . '[]'] = $entry1->id();
    $this->drupalPostForm('node/add/article', $edit, t('Save'));

    // Check that the entry is displayed when the node is viewed.
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
    $this->drupalGet('node/' . $node->id());
    $this->assertText($entry1->getName(), 'Entry is displayed when viewing the node.');

    $this->clickLink(t('Edit'));
    $this->assertText($entry1->getName(), 'Entry is displayed when editing the node.');
    $this->drupalPostForm(NULL, [], t('Save'));
    $this->assertText($entry1->getName(), 'Entry is displayed after saving the node with no changes.');

    // Edit the node with a different entry.
    $edit[$this->field->getName() . '[]'] = $entry2->id();
    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));

    $this->drupalGet('node/' . $node->id());
    $this->assertText($entry2->getName(), 'Entry is displayed when viewing the node.');

    // Preview the node.
    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
    $this->assertUniqueText($entry2->getName(), 'Entry is displayed when previewing the node.');
    $this->drupalPostForm('node/' . $node->id() . '/edit', NULL, t('Preview'));
    $this->assertUniqueText($entry2->getName(), 'Entry is displayed when previewing the node again.');
  }

  /**
   * Test entry creation with a free-tagging outline from the node form.
   */
  public function testNodeEntryCreationAndDeletion() {
    // Enable tags in the outline.
    $field = $this->field;
    \Drupal::service('entity_display.repository')
      ->getFormDisplay($field->getTargetEntityTypeId(), $field->getTargetBundle())
      ->setComponent($field->getName(), [
        'type' => 'entity_reference_autocomplete_tags',
        'settings' => [
          'placeholder' => 'Start typing here.',
        ],
      ])
      ->save();
    // Prefix the entries with a letter to ensure there is no clash in the first
    // three letters.
    // @see https://www.drupal.org/node/2397691
    $entries = [
      'entry1' => 'a' . $this->randomMachineName(),
      'entry2' => 'b' . $this->randomMachineName(),
      'entry3' => 'c' . $this->randomMachineName() . ', ' . $this->randomMachineName(),
      'entry4' => 'd' . $this->randomMachineName(),
    ];

    $edit = [];
    $edit['title[0][value]'] = $this->randomMachineName();
    $edit['body[0][value]'] = $this->randomMachineName();
    // Insert the entries in a comma separated list. Outline 1 is a
    // free-tagging field created by the default profile.
    $edit[$field->getName() . '[target_id]'] = Tags::implode($entries);

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

    // Preview and verify the entries appear but are not created.
    $this->drupalPostForm(NULL, $edit, t('Preview'));
    foreach ($entries as $entry) {
      $this->assertText($entry, 'The entry appears on the node preview.');
    }
    $tree = $this->container->get('entity_type.manager')->getStorage('outline_entry')->loadTree($this->outline->id());
    $this->assertTrue(empty($tree), 'The entries are not created on preview.');

    // outline.module does not maintain its static caches.
    outline_entrys_static_reset();

    // Save, creating the entries.
    $this->drupalPostForm('node/add/article', $edit, t('Save'));
    $this->assertText(t('@type @title has been created.', ['@type' => t('Article'), '@title' => $edit['title[0][value]']]), 'The node was created successfully.');

    // Verify that the creation message contains a link to a node.
    $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'node/']);
    $this->assert(isset($view_link), 'The message area contains a link to a node');

    foreach ($entries as $entry) {
      $this->assertText($entry, 'The entry was saved and appears on the node page.');
    }

    // Get the created entries.
    $entry_objects = [];
    foreach ($entries as $key => $entry) {
      $entry_objects[$key] = outline_entry_load_multiple_by_name($entry);
      $entry_objects[$key] = reset($entry_objects[$key]);
    }

    // Get the node.
    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);

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

    // Delete entry 1 from the entry edit page.
    $this->drupalGet('outline/entry/' . $entry_objects['entry1']->id() . '/edit');
    $this->clickLink(t('Delete'));
    $this->drupalPostForm(NULL, NULL, t('Delete'));

    // Delete entry 2 from the entry delete page.
    $this->drupalGet('outline/entry/' . $entry_objects['entry2']->id() . '/delete');
    $this->drupalPostForm(NULL, [], t('Delete'));
    $entry_names = [$entry_objects['entry3']->getName(), $entry_objects['entry4']->getName()];

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

    foreach ($entry_names as $entry_name) {
      $this->assertText($entry_name, new FormattableMarkup('The entry %name appears on the node page after two entries, %deleted1 and %deleted2, were deleted.', ['%name' => $entry_name, '%deleted1' => $entry_objects['entry1']->getName(), '%deleted2' => $entry_objects['entry2']->getName()]));
    }
    $this->assertNoText($entry_objects['entry1']->getName(), new FormattableMarkup('The deleted entry %name does not appear on the node page.', ['%name' => $entry_objects['entry1']->getName()]));
    $this->assertNoText($entry_objects['entry2']->getName(), new FormattableMarkup('The deleted entry %name does not appear on the node page.', ['%name' => $entry_objects['entry2']->getName()]));
  }

  /**
   * Save, edit and delete a entry using the user interface.
   */
  public function testEntryInterface() {
    \Drupal::service('module_installer')->install(['views']);
    $edit = [
      'name[0][value]' => $this->randomMachineName(12),
      'description[0][value]' => $this->randomMachineName(100),
    ];
    // Explicitly set the parents field to 'root', to ensure that
    // EntryForm::save() handles the invalid entry ID correctly.
    $edit['parent[]'] = [0];

    // Create the entry to edit.
    $this->drupalPostForm('admin/structure/outline/manage/' . $this->outline->id() . '/add', $edit, t('Save'));

    $entries = outline_entry_load_multiple_by_name($edit['name[0][value]']);
    $entry = reset($entries);
    $this->assertNotNull($entry, 'Entry found in database.');

    // Submitting a entry takes us to the add page; we need the List page.
    $this->drupalGet('admin/structure/outline/manage/' . $this->outline->id() . '/overview');

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

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

    $edit = [
      'name[0][value]' => $this->randomMachineName(14),
      'description[0][value]' => $this->randomMachineName(102),
    ];

    // Edit the entry.
    $this->drupalPostForm('outline/entry/' . $entry->id() . '/edit', $edit, t('Save'));

    // Check that the entry is still present at admin UI after edit.
    $this->drupalGet('admin/structure/outline/manage/' . $this->outline->id() . '/overview');
    $this->assertText($edit['name[0][value]'], 'The randomly generated entry name is present.');
    $this->assertSession()->linkExists(t('Edit'));

    // Check the entry link can be clicked through to the entry page.
    $this->clickLink($edit['name[0][value]']);
    $this->assertSession()->statusCodeEquals(200);

    // View the entry and check that it is correct.
    $this->drupalGet('outline/entry/' . $entry->id());
    $this->assertText($edit['name[0][value]'], 'The randomly generated entry name is present.');
    $this->assertText($edit['description[0][value]'], 'The randomly generated entry description is present.');

    // Did this page request display a 'entry-listing-heading'?
    $this->assertSession()->elementExists('xpath', '//div[contains(@class, "field--name-description")]');
    // Check that it does NOT show a description when description is blank.
    $entry->setDescription(NULL);
    $entry->save();
    $this->drupalGet('outline/entry/' . $entry->id());
    $this->assertSession()->elementNotExists('xpath', '//div[contains(@class, "field--entity-outline-entry--description")]');

    // Check that the description value is processed.
    $value = $this->randomMachineName();
    $entry->setDescription($value);
    $entry->save();
    $this->assertEqual($entry->description->processed, "<p>$value</p>\n");

    // Check that the entry feed page is working.
    $this->drupalGet('outline/entry/' . $entry->id() . '/feed');

    // Delete the entry.
    $this->drupalGet('outline/entry/' . $entry->id() . '/edit');
    $this->clickLink(t('Delete'));
    $this->drupalPostForm(NULL, NULL, t('Delete'));

    // Assert that the entry no longer exists.
    $this->drupalGet('outline/entry/' . $entry->id());
    $this->assertSession()->statusCodeEquals(404);
  }

  /**
   * Save, edit and delete a entry using the user interface.
   */
  public function testEntryReorder() {
    $assert = $this->assertSession();
    $this->createEntry($this->outline);
    $this->createEntry($this->outline);
    $this->createEntry($this->outline);

    $outline_storage = $this->container->get('entity_type.manager')->getStorage('outline_entry');

    // Fetch the created entries in the default alphabetical order, i.e. entry1
    // precedes entry2 alphabetically, and entry2 precedes entry3.
    $outline_storage->resetCache();
    list($entry1, $entry2, $entry3) = $outline_storage->loadTree($this->outline->id(), 0, NULL, TRUE);

    $this->drupalGet('admin/structure/outline/manage/' . $this->outline->id() . '/overview');

    // Each entry 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 entry2,
    // entry3, entry1 by setting weight property, make entry3 a child of entry2 by
    // setting the parent and depth properties, and update all hidden fields.
    $hidden_edit = [
      'entries[tid:' . $entry2->id() . ':0][entry][tid]' => $entry2->id(),
      'entries[tid:' . $entry2->id() . ':0][entry][parent]' => 0,
      'entries[tid:' . $entry2->id() . ':0][entry][depth]' => 0,
      'entries[tid:' . $entry3->id() . ':0][entry][tid]' => $entry3->id(),
      'entries[tid:' . $entry3->id() . ':0][entry][parent]' => $entry2->id(),
      'entries[tid:' . $entry3->id() . ':0][entry][depth]' => 1,
      'entries[tid:' . $entry1->id() . ':0][entry][tid]' => $entry1->id(),
      'entries[tid:' . $entry1->id() . ':0][entry][parent]' => 0,
      'entries[tid:' . $entry1->id() . ':0][entry][depth]' => 0,
    ];
    // Because we can't post hidden form elements, we have to change them in
    // code here, and then submit.
    foreach ($hidden_edit as $field => $value) {
      $node = $assert->hiddenFieldExists($field);
      $node->setValue($value);
    }
    // Edit non-hidden elements within drupalPostForm().
    $edit = [
      'entries[tid:' . $entry2->id() . ':0][weight]' => 0,
      'entries[tid:' . $entry3->id() . ':0][weight]' => 1,
      'entries[tid:' . $entry1->id() . ':0][weight]' => 2,
    ];
    $this->drupalPostForm(NULL, $edit, 'Save');

    $outline_storage->resetCache();
    $entries = $outline_storage->loadTree($this->outline->id());
    $this->assertEqual($entries[0]->tid, $entry2->id(), 'Entry 2 was moved above entry 1.');
    $this->assertEqual($entries[1]->parents, [$entry2->id()], 'Entry 3 was made a child of entry 2.');
    $this->assertEqual($entries[2]->tid, $entry1->id(), 'Entry 1 was moved below entry 2.');

    $this->drupalPostForm('admin/structure/outline/manage/' . $this->outline->id() . '/overview', [], t('Reset to alphabetical'));
    // Submit confirmation form.
    $this->drupalPostForm(NULL, [], t('Reset to alphabetical'));
    // Ensure form redirected back to overview.
    $this->assertUrl('admin/structure/outline/manage/' . $this->outline->id() . '/overview');

    $outline_storage->resetCache();
    $entries = $outline_storage->loadTree($this->outline->id(), 0, NULL, TRUE);
    $this->assertEqual($entries[0]->id(), $entry1->id(), 'Entry 1 was moved to back above entry 2.');
    $this->assertEqual($entries[1]->id(), $entry2->id(), 'Entry 2 was moved to back below entry 1.');
    $this->assertEqual($entries[2]->id(), $entry3->id(), 'Entry 3 is still below entry 2.');
    $this->assertEqual($entries[2]->parents, [$entry2->id()], 'Entry 3 is still a child of entry 2.');
  }

  /**
   * Test saving a entry with multiple parents through the UI.
   */
  public function testEntryMultipleParentsInterface() {
    // Add a new entry to the outline so that we can have multiple parents.
    $parent = $this->createEntry($this->outline);

    // Add a new entry with multiple parents.
    $edit = [
      'name[0][value]' => $this->randomMachineName(12),
      'description[0][value]' => $this->randomMachineName(100),
      'parent[]' => [0, $parent->id()],
    ];
    // Save the new entry.
    $this->drupalPostForm('admin/structure/outline/manage/' . $this->outline->id() . '/add', $edit, t('Save'));

    // Check that the entry was successfully created.
    $entries = outline_entry_load_multiple_by_name($edit['name[0][value]']);
    $entry = reset($entries);
    $this->assertNotNull($entry, 'Entry found in database.');
    $this->assertEqual($edit['name[0][value]'], $entry->getName(), 'Entry name was successfully saved.');
    $this->assertEqual($edit['description[0][value]'], $entry->getDescription(), 'Entry description was successfully saved.');
    // Check that the parent tid is still there. The other parent (<root>) is
    // not added by \Drupal\outline\EntryStorageInterface::loadParents().
    $parents = $this->container->get('entity_type.manager')->getStorage('outline_entry')->loadParents($entry->id());
    $parent = reset($parents);
    $this->assertEqual($edit['parent[]'][1], $parent->id(), 'Entry parents were successfully saved.');
  }

  /**
   * Test outline_entry_load_multiple_by_name().
   */
  public function testOutlineGetEntryByName() {
    $entry = $this->createEntry($this->outline);

    // Load the entry with the exact name.
    $entries = outline_entry_load_multiple_by_name($entry->getName());
    $this->assertTrue(isset($entries[$entry->id()]), 'Entry loaded using exact name.');

    // Load the entry with space concatenated.
    $entries = outline_entry_load_multiple_by_name('  ' . $entry->getName() . '   ');
    $this->assertTrue(isset($entries[$entry->id()]), 'Entry loaded with extra whitespace.');

    // Load the entry with name uppercased.
    $entries = outline_entry_load_multiple_by_name(strtoupper($entry->getName()));
    $this->assertTrue(isset($entries[$entry->id()]), 'Entry loaded with uppercased name.');

    // Load the entry with name lowercased.
    $entries = outline_entry_load_multiple_by_name(strtolower($entry->getName()));
    $this->assertTrue(isset($entries[$entry->id()]), 'Entry loaded with lowercased name.');

    // Try to load an invalid entry name.
    $entries = outline_entry_load_multiple_by_name('Banana');
    $this->assertEmpty($entries, 'No entry loaded with an invalid name.');

    // Try to load the entry using a substring of the name.
    $entries = outline_entry_load_multiple_by_name(mb_substr($entry->getName(), 2), 'No entry loaded with a substring of the name.');
    $this->assertEmpty($entries);

    // Create a new entry in a different outline with the same name.
    $new_outline = $this->createOutline();
    $new_entry = Entry::create([
      'name' => $entry->getName(),
      'oid' => $new_outline->id(),
    ]);
    $new_entry->save();

    // Load multiple entries with the same name.
    $entries = outline_entry_load_multiple_by_name($entry->getName());
    $this->assertCount(2, $entries, 'Two entries loaded with the same name.');

    // Load single entry when restricted to one outline.
    $entries = outline_entry_load_multiple_by_name($entry->getName(), $this->outline->id());
    $this->assertCount(1, $entries, 'One entry loaded when restricted by outline.');
    $this->assertTrue(isset($entries[$entry->id()]), 'Entry loaded using exact name and outline machine name.');

    // Create a new entry with another name.
    $entry2 = $this->createEntry($this->outline);

    // Try to load a entry by name that doesn't exist in this outline but
    // exists in another outline.
    $entries = outline_entry_load_multiple_by_name($entry2->getName(), $new_outline->id());
    $this->assertEmpty($entries, 'Invalid entry name restricted by outline machine name not loaded.');

    // Try to load entries filtering by a non-existing outline.
    $entries = outline_entry_load_multiple_by_name($entry2->getName(), 'non_existing_outline');
    $this->assertCount(0, $entries, 'No entries loaded when restricted by a non-existing outline.');
  }

  /**
   * Tests that editing and saving a node with no changes works correctly.
   */
  public function testReSavingTags() {
    // Enable tags in the outline.
    $field = $this->field;
    \Drupal::service('entity_display.repository')
      ->getFormDisplay($field->getTargetEntityTypeId(), $field->getTargetBundle())
      ->setComponent($field->getName(), [
        'type' => 'entity_reference_autocomplete_tags',
      ])
      ->save();

    // Create a entry and a node using it.
    $entry = $this->createEntry($this->outline);
    $edit = [];
    $edit['title[0][value]'] = $this->randomMachineName(8);
    $edit['body[0][value]'] = $this->randomMachineName(16);
    $edit[$this->field->getName() . '[target_id]'] = $entry->getName();
    $this->drupalPostForm('node/add/article', $edit, t('Save'));

    // Check that the entry is displayed when editing and saving the node with no
    // changes.
    $this->clickLink(t('Edit'));
    $this->assertRaw($entry->getName(), 'Entry is displayed when editing the node.');
    $this->drupalPostForm(NULL, [], t('Save'));
    $this->assertRaw($entry->getName(), 'Entry is displayed after saving the node with no changes.');
  }

  /**
   * Check the breadcrumb on edit and delete a entry page.
   */
  public function testEntryBreadcrumbs() {
    $edit = [
      'name[0][value]' => $this->randomMachineName(14),
      'description[0][value]' => $this->randomMachineName(100),
      'parent[]' => [0],
    ];

    // Create the entry.
    $this->drupalPostForm('admin/structure/outline/manage/' . $this->outline->id() . '/add', $edit, 'Save');

    $entries = outline_entry_load_multiple_by_name($edit['name[0][value]']);
    $entry = reset($entries);
    $this->assertNotNull($entry, 'Entry found in database.');

    // Check the breadcrumb on the entry edit page.
    $this->drupalGet('outline/entry/' . $entry->id() . '/edit');
    $breadcrumbs = $this->getSession()->getPage()->findAll('css', 'nav.breadcrumb ol li a');
    $this->assertCount(2, $breadcrumbs, 'The breadcrumbs are present on the page.');
    $this->assertIdentical($breadcrumbs[0]->getText(), 'Home', 'First breadcrumb text is Home');
    $this->assertIdentical($breadcrumbs[1]->getText(), $entry->label(), 'Second breadcrumb text is entry name on entry edit page.');
    $this->assertEscaped($breadcrumbs[1]->getText());

    // Check the breadcrumb on the entry delete page.
    $this->drupalGet('outline/entry/' . $entry->id() . '/delete');
    $breadcrumbs = $this->getSession()->getPage()->findAll('css', 'nav.breadcrumb ol li a');
    $this->assertCount(2, $breadcrumbs, 'The breadcrumbs are present on the page.');
    $this->assertIdentical($breadcrumbs[0]->getText(), 'Home', 'First breadcrumb text is Home');
    $this->assertIdentical($breadcrumbs[1]->getText(), $entry->label(), 'Second breadcrumb text is entry name on entry delete page.');
    $this->assertEscaped($breadcrumbs[1]->getText());
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc