You are here

public function SearchRankingTest::testRankings in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/search/tests/src/Functional/SearchRankingTest.php \Drupal\Tests\search\Functional\SearchRankingTest::testRankings()

File

core/modules/search/tests/src/Functional/SearchRankingTest.php, line 60

Class

SearchRankingTest
Indexes content and tests ranking factors.

Namespace

Drupal\Tests\search\Functional

Code

public function testRankings() {

  // Add a comment field.
  $this
    ->addDefaultCommentField('node', 'page');

  // Build a list of the rankings to test.
  $node_ranks = [
    'sticky',
    'promote',
    'relevance',
    'recent',
    'comments',
    'views',
  ];

  // Create nodes for testing.
  $nodes = [];
  foreach ($node_ranks as $node_rank) {
    $settings = [
      'type' => 'page',
      'comment' => [
        [
          'status' => CommentItemInterface::HIDDEN,
        ],
      ],
      'title' => 'Drupal rocks',
      'body' => [
        [
          'value' => "Drupal's search rocks",
        ],
      ],
      // Node is one day old.
      'created' => REQUEST_TIME - 24 * 3600,
      'sticky' => 0,
      'promote' => 0,
    ];
    foreach ([
      0,
      1,
    ] as $num) {
      if ($num == 1) {
        switch ($node_rank) {
          case 'sticky':
          case 'promote':
            $settings[$node_rank] = 1;
            break;
          case 'relevance':
            $settings['body'][0]['value'] .= " really rocks";
            break;
          case 'recent':

            // Node is 1 hour hold.
            $settings['created'] = REQUEST_TIME - 3600;
            break;
          case 'comments':
            $settings['comment'][0]['status'] = CommentItemInterface::OPEN;
            break;
        }
      }
      $nodes[$node_rank][$num] = $this
        ->drupalCreateNode($settings);
    }
  }

  // Add a comment to one of the nodes.
  $edit = [];
  $edit['subject[0][value]'] = 'my comment title';
  $edit['comment_body[0][value]'] = 'some random comment';
  $this
    ->drupalGet('comment/reply/node/' . $nodes['comments'][1]
    ->id() . '/comment');
  $this
    ->submitForm($edit, 'Preview');
  $this
    ->submitForm($edit, 'Save');

  // Enable counting of statistics.
  $this
    ->config('statistics.settings')
    ->set('count_content_views', 1)
    ->save();

  // Simulating content views is kind of difficult in the test. Leave that
  // to the Statistics module. So instead go ahead and manually update the
  // counter for this node.
  $nid = $nodes['views'][1]
    ->id();
  Database::getConnection()
    ->insert('node_counter')
    ->fields([
    'totalcount' => 5,
    'daycount' => 5,
    'timestamp' => REQUEST_TIME,
    'nid' => $nid,
  ])
    ->execute();

  // Run cron to update the search index and comment/statistics totals.
  $this
    ->cronRun();

  // Test that the settings form displays the content ranking section.
  $this
    ->drupalGet('admin/config/search/pages/manage/node_search');
  $this
    ->assertSession()
    ->pageTextContains('Content ranking');

  // Check that all rankings are visible and set to 0.
  foreach ($node_ranks as $node_rank) {
    $this
      ->assertSession()
      ->optionExists('edit-rankings-' . $node_rank . '-value', '0');
  }

  // Test each of the possible rankings.
  $edit = [];
  foreach ($node_ranks as $node_rank) {

    // Enable the ranking we are testing.
    $edit['rankings[' . $node_rank . '][value]'] = 10;
    $this
      ->drupalGet('admin/config/search/pages/manage/node_search');
    $this
      ->submitForm($edit, 'Save search page');
    $this
      ->drupalGet('admin/config/search/pages/manage/node_search');
    $this
      ->assertSession()
      ->optionExists('edit-rankings-' . $node_rank . '-value', '10');

    // Reload the plugin to get the up-to-date values.
    $this->nodeSearch = SearchPage::load('node_search');

    // Do the search and assert the results.
    $this->nodeSearch
      ->getPlugin()
      ->setSearch('rocks', [], []);
    $set = $this->nodeSearch
      ->getPlugin()
      ->execute();
    $this
      ->assertEquals($nodes[$node_rank][1]
      ->id(), $set[0]['node']
      ->id(), 'Search ranking "' . $node_rank . '" order.');

    // Clear this ranking for the next test.
    $edit['rankings[' . $node_rank . '][value]'] = 0;
  }

  // Save the final node_rank change then check that all rankings are visible
  // and have been set back to 0.
  $this
    ->drupalGet('admin/config/search/pages/manage/node_search');
  $this
    ->submitForm($edit, 'Save search page');
  $this
    ->drupalGet('admin/config/search/pages/manage/node_search');
  foreach ($node_ranks as $node_rank) {
    $this
      ->assertSession()
      ->optionExists('edit-rankings-' . $node_rank . '-value', '0');
  }

  // Try with sticky, then promoted. This is a test for issue
  // https://www.drupal.org/node/771596.
  $node_ranks = [
    'sticky' => 10,
    'promote' => 1,
    'relevance' => 0,
    'recent' => 0,
    'comments' => 0,
    'views' => 0,
  ];
  $configuration = $this->nodeSearch
    ->getPlugin()
    ->getConfiguration();
  foreach ($node_ranks as $var => $value) {
    $configuration['rankings'][$var] = $value;
  }
  $this->nodeSearch
    ->getPlugin()
    ->setConfiguration($configuration);
  $this->nodeSearch
    ->save();

  // Do the search and assert the results. The sticky node should show up
  // first, then the promoted node, then all the rest.
  $this->nodeSearch
    ->getPlugin()
    ->setSearch('rocks', [], []);
  $set = $this->nodeSearch
    ->getPlugin()
    ->execute();
  $this
    ->assertEquals($nodes['sticky'][1]
    ->id(), $set[0]['node']
    ->id(), 'Search ranking for sticky first worked.');
  $this
    ->assertEquals($nodes['promote'][1]
    ->id(), $set[1]['node']
    ->id(), 'Search ranking for promoted second worked.');

  // Try with recent, then comments. This is a test for issues
  // https://www.drupal.org/node/771596 and
  // https://www.drupal.org/node/303574.
  $node_ranks = [
    'sticky' => 0,
    'promote' => 0,
    'relevance' => 0,
    'recent' => 10,
    'comments' => 1,
    'views' => 0,
  ];
  $configuration = $this->nodeSearch
    ->getPlugin()
    ->getConfiguration();
  foreach ($node_ranks as $var => $value) {
    $configuration['rankings'][$var] = $value;
  }
  $this->nodeSearch
    ->getPlugin()
    ->setConfiguration($configuration);
  $this->nodeSearch
    ->save();

  // Do the search and assert the results. The recent node should show up
  // first, then the commented node, then all the rest.
  $this->nodeSearch
    ->getPlugin()
    ->setSearch('rocks', [], []);
  $set = $this->nodeSearch
    ->getPlugin()
    ->execute();
  $this
    ->assertEquals($nodes['recent'][1]
    ->id(), $set[0]['node']
    ->id(), 'Search ranking for recent first worked.');
  $this
    ->assertEquals($nodes['comments'][1]
    ->id(), $set[1]['node']
    ->id(), 'Search ranking for comments second worked.');
}