You are here

public function ListControllerTest::testListController in Entity Usage 8.3

Same name and namespace in other branches
  1. 8.4 tests/src/FunctionalJavascript/ListControllerTest.php \Drupal\Tests\entity_usage\FunctionalJavascript\ListControllerTest::testListController()
  2. 8 tests/src/FunctionalJavascript/ListControllerTest.php \Drupal\Tests\entity_usage\FunctionalJavascript\ListControllerTest::testListController()
  3. 8.2 tests/src/FunctionalJavascript/ListControllerTest.php \Drupal\Tests\entity_usage\FunctionalJavascript\ListControllerTest::testListController()

Tests the page listing the usage of entities.

@covers \Drupal\entity_usage\Controller\ListUsageController::listUsagePage

File

tests/src/FunctionalJavascript/ListControllerTest.php, line 48

Class

ListControllerTest
Tests the page listing the usage of a given entity.

Namespace

Drupal\Tests\entity_usage\FunctionalJavascript

Code

public function testListController() {
  $session = $this
    ->getSession();
  $page = $session
    ->getPage();
  $assert_session = $this
    ->assertSession();

  // Create node 1.
  $this
    ->drupalGet('/node/add/eu_test_ct');
  $page
    ->fillField('title[0][value]', 'Node 1');
  $page
    ->pressButton('Save');
  $session
    ->wait(500);
  $this
    ->saveHtmlOutput();
  $assert_session
    ->pageTextContains('eu_test_ct Node 1 has been created.');

  /** @var \Drupal\node\NodeInterface $node1 */
  $node1 = $this
    ->getLastEntityOfType('node', TRUE);

  // Create node 2 referencing node 1 using reference field.
  $this
    ->drupalGet('/node/add/eu_test_ct');
  $page
    ->fillField('title[0][value]', 'Node 2');
  $page
    ->fillField('field_eu_test_related_nodes[0][target_id]', 'Node 1 (1)');
  $page
    ->pressButton('Save');
  $session
    ->wait(500);
  $this
    ->saveHtmlOutput();
  $assert_session
    ->pageTextContains('eu_test_ct Node 2 has been created.');
  $node2 = $this
    ->getLastEntityOfType('node', TRUE);

  // Create node 3 also referencing node 1 in an embed text field.
  $uuid_node1 = $node1
    ->uuid();
  $embedded_text = '<drupal-entity data-embed-button="node" data-entity-embed-display="entity_reference:entity_reference_label" data-entity-embed-display-settings="{&quot;link&quot;:1}" data-entity-type="node" data-entity-uuid="' . $uuid_node1 . '"></drupal-entity>';
  $node3 = Node::create([
    'type' => 'eu_test_ct',
    'title' => 'Node 3',
    'field_eu_test_rich_text' => [
      'value' => $embedded_text,
      'format' => 'eu_test_text_format',
    ],
  ]);
  $node3
    ->save();
  $this
    ->triggerPostRequestTracking();

  // Visit the page that tracks usage of node 1 and check everything is there.
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $assert_session
    ->pageTextContains('Entity usage information for Node 1');

  // Check table headers are present.
  $assert_session
    ->pageTextContains('Entity');
  $assert_session
    ->pageTextContains('Type');
  $assert_session
    ->pageTextContains('Language');
  $assert_session
    ->pageTextContains('Status');

  // Make sure that all elements of the table are the expected ones.
  $first_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[1]/td[1]/a');
  $this
    ->assertEquals('Node 3', $first_row_title_link
    ->getText());
  $this
    ->assertContains($node3
    ->toUrl()
    ->toString(), $first_row_title_link
    ->getAttribute('href'));
  $first_row_type = $this
    ->xpath('//table/tbody/tr[1]/td[2]')[0];
  $this
    ->assertEquals('Content', $first_row_type
    ->getText());
  $first_row_langcode = $this
    ->xpath('//table/tbody/tr[1]/td[3]')[0];
  $this
    ->assertEquals('English', $first_row_langcode
    ->getText());
  $first_row_status = $this
    ->xpath('//table/tbody/tr[1]/td[4]')[0];
  $this
    ->assertEquals('Published', $first_row_status
    ->getText());
  $second_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[2]/td[1]/a');
  $this
    ->assertEquals('Node 2', $second_row_title_link
    ->getText());
  $this
    ->assertContains($node2
    ->toUrl()
    ->toString(), $second_row_title_link
    ->getAttribute('href'));
  $second_row_type = $this
    ->xpath('//table/tbody/tr[2]/td[2]')[0];
  $this
    ->assertEquals('Content', $second_row_type
    ->getText());
  $second_row_langcode = $this
    ->xpath('//table/tbody/tr[2]/td[3]')[0];
  $this
    ->assertEquals('English', $second_row_langcode
    ->getText());
  $second_row_status = $this
    ->xpath('//table/tbody/tr[2]/td[4]')[0];
  $this
    ->assertEquals('Published', $second_row_status
    ->getText());
  $assert_session
    ->pageTextNotContains('Note: This page only includes usages in the current revisions of referencing entities');

  // If we unpublish Node 2 its status is correctly reflected.

  /** @var \Drupal\node\NodeInterface $node2 */
  $node2
    ->setUnpublished();
  $node2
    ->setNewRevision();
  $node2
    ->save();
  $this
    ->triggerPostRequestTracking();
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $second_row_status = $this
    ->xpath('//table/tbody/tr[2]/td[4]')[0];
  $this
    ->assertEquals('Unpublished', $second_row_status
    ->getText());

  // Artificially create some garbage in the database and make sure it doesn't
  // show up on the usage page.
  \Drupal::database()
    ->insert('entity_usage')
    ->fields([
    'target_id' => $node1
      ->id(),
    'target_type' => $node1
      ->getEntityTypeId(),
    'source_id' => '1234',
    'source_type' => 'user',
    'source_langcode' => 'en',
    'source_vid' => '5678',
  ])
    ->execute();

  // Check the usage is there.
  $usage = \Drupal::service('entity_usage.usage')
    ->listSources($node1);
  $this
    ->assertTrue(!empty($usage['user']));

  // Check the usage list skips it when showing results.
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $assert_session
    ->pageTextContains('Entity usage information for Node 1');
  $assert_session
    ->elementNotContains('css', 'table', '1234');
  $assert_session
    ->elementNotContains('css', 'table', 'user');

  // If some sources reference our entity in a previous revision, an
  // additional message is displayed.
  $node2->field_eu_test_related_nodes = NULL;
  $node2
    ->setNewRevision();
  $node2
    ->save();
  $this
    ->triggerPostRequestTracking();
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $assert_session
    ->pageTextContains('Entity usage information for Node 1');
  $assert_session
    ->pageTextNotContains('Node 2');

  // Populate it back and verify it appears there again.
  $node2->field_eu_test_related_nodes->target_id = $node1
    ->id();
  $node2
    ->setNewRevision();
  $node2
    ->save();
  $this
    ->triggerPostRequestTracking();
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $assert_session
    ->pageTextContains('Entity usage information for Node 1');
  $assert_session
    ->pageTextContains('Node 2');

  // Make sure we only have 2 rows.
  $this
    ->assertEquals(2, count($this
    ->xpath('//table/tbody/tr')));

  // Create some additional languages.
  foreach ([
    'es',
  ] as $langcode) {
    ConfigurableLanguage::createFromLangcode($langcode)
      ->save();
  }

  // Let the logged-in user do multi-lingual stuff.

  /** @var \Drupal\user\RoleInterface $authenticated_role */
  $authenticated_role = Role::load('authenticated');
  $authenticated_role
    ->grantPermission('administer content translation');
  $authenticated_role
    ->grantPermission('translate any entity');
  $authenticated_role
    ->grantPermission('create content translations');
  $authenticated_role
    ->grantPermission('administer languages');
  $authenticated_role
    ->grantPermission('administer entity usage');
  $authenticated_role
    ->grantPermission('access entity usage statistics');
  $authenticated_role
    ->save();

  // Set our content type as translatable.
  $this
    ->drupalGet('/admin/config/regional/content-language');
  $page
    ->checkField('entity_types[node]');
  $page
    ->checkField('settings[node][eu_test_ct][translatable]');
  $page
    ->pressButton('Save configuration');
  $session
    ->wait(500);
  $this
    ->saveHtmlOutput();
  $assert_session
    ->pageTextContains('Settings successfully updated.');

  // Translate $node2 and check its translation shows up.
  $this
    ->drupalGet("/es/node/{$node2->id()}/translations/add/en/es");
  $page
    ->fillField('field_eu_test_related_nodes[0][target_id]', "Node 1 ({$node1->id()})");

  // Ensure we are creating a new revision.
  $revision_tab = $page
    ->find('css', 'a[href="#edit-revision-information"]');
  $revision_tab
    ->click();
  $page
    ->checkField('Create new revision (all languages)');
  $assert_session
    ->checkboxChecked('Create new revision (all languages)');
  $page
    ->pressButton('Save (this translation)');
  $session
    ->wait(500);
  $this
    ->saveHtmlOutput();
  $assert_session
    ->pageTextContains('eu_test_ct Node 2 has been updated.');

  // Usage now should be updated.
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $first_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[1]/td[1]/a');
  $this
    ->assertEquals('Node 3', $first_row_title_link
    ->getText());
  $this
    ->assertContains($node3
    ->toUrl()
    ->toString(), $first_row_title_link
    ->getAttribute('href'));
  $first_row_type = $this
    ->xpath('//table/tbody/tr[1]/td[2]')[0];
  $this
    ->assertEquals('Content', $first_row_type
    ->getText());
  $first_row_langcode = $this
    ->xpath('//table/tbody/tr[1]/td[3]')[0];
  $this
    ->assertEquals('English', $first_row_langcode
    ->getText());
  $first_row_status = $this
    ->xpath('//table/tbody/tr[1]/td[4]')[0];
  $this
    ->assertEquals('Published', $first_row_status
    ->getText());
  $second_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[2]/td[1]/a');
  $this
    ->assertEquals('Node 2', $second_row_title_link
    ->getText());
  $this
    ->assertContains($node2
    ->toUrl()
    ->toString(), $second_row_title_link
    ->getAttribute('href'));
  $second_row_type = $this
    ->xpath('//table/tbody/tr[2]/td[2]')[0];
  $this
    ->assertEquals('Content', $second_row_type
    ->getText());
  $second_row_langcode = $this
    ->xpath('//table/tbody/tr[2]/td[3]')[0];
  $this
    ->assertEquals('English', $second_row_langcode
    ->getText());
  $second_row_status = $this
    ->xpath('//table/tbody/tr[2]/td[4]')[0];
  $this
    ->assertEquals('Unpublished', $second_row_status
    ->getText());
  $third_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[3]/td[1]/a');
  $this
    ->assertEquals('Node 2', $third_row_title_link
    ->getText());
  $this
    ->assertContains($node2
    ->toUrl()
    ->toString(), $third_row_title_link
    ->getAttribute('href'));
  $third_row_type = $this
    ->xpath('//table/tbody/tr[3]/td[2]')[0];
  $this
    ->assertEquals('Content', $third_row_type
    ->getText());
  $third_row_langcode = $this
    ->xpath('//table/tbody/tr[3]/td[3]')[0];
  $this
    ->assertEquals('Spanish', $third_row_langcode
    ->getText());
  $third_row_status = $this
    ->xpath('//table/tbody/tr[3]/td[4]')[0];
  $this
    ->assertEquals('Unpublished', $third_row_status
    ->getText());

  // Verify that it's possible to control the number of items per page.
  // Initially we have no pager since two rows fit in one page.
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");
  $assert_session
    ->elementNotExists('css', 'ul.pager__items');
  $this
    ->drupalGet('/admin/config/entity-usage/settings');

  // Set items per page to 1.
  $page
    ->find('css', 'input[name="usage_controller_items_per_group"]')
    ->setValue('1');
  $page
    ->pressButton('Save configuration');
  $session
    ->wait(500);
  $this
    ->saveHtmlOutput();
  $assert_session
    ->pageTextContains('The configuration options have been saved.');
  $this
    ->drupalGet("/admin/content/entity-usage/node/{$node1->id()}");

  // Pager is there.
  $pager_element = $assert_session
    ->elementExists('css', 'ul.pager__items');

  // First node is on the first page, the second node on the next page.
  $first_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[1]/td[1]/a');
  $this
    ->assertEquals('Node 3', $first_row_title_link
    ->getText());
  $assert_session
    ->elementNotExists('xpath', '//table/tbody/tr[2]');
  $assert_session
    ->pageTextNotContains('Node 2');
  $pager_element
    ->find('css', '.pager__item--next a')
    ->click();
  $first_row_title_link = $assert_session
    ->elementExists('xpath', '//table/tbody/tr[1]/td[1]/a');
  $this
    ->assertEquals('Node 2', $first_row_title_link
    ->getText());
  $assert_session
    ->elementNotExists('xpath', '//table/tbody/tr[2]');
  $assert_session
    ->pageTextNotContains('Node 3');
}