annotate core/modules/search/src/Tests/SearchRankingTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\search\Tests;
Chris@0 4
Chris@0 5 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
Chris@0 6 use Drupal\comment\Tests\CommentTestTrait;
Chris@0 7 use Drupal\Core\Url;
Chris@0 8 use Drupal\filter\Entity\FilterFormat;
Chris@0 9 use Drupal\search\Entity\SearchPage;
Chris@0 10
Chris@0 11 /**
Chris@0 12 * Indexes content and tests ranking factors.
Chris@0 13 *
Chris@0 14 * @group search
Chris@0 15 */
Chris@0 16 class SearchRankingTest extends SearchTestBase {
Chris@0 17
Chris@0 18 use CommentTestTrait;
Chris@0 19
Chris@0 20 /**
Chris@0 21 * The node search page.
Chris@0 22 *
Chris@0 23 * @var \Drupal\search\SearchPageInterface
Chris@0 24 */
Chris@0 25 protected $nodeSearch;
Chris@0 26
Chris@0 27 /**
Chris@0 28 * Modules to enable.
Chris@0 29 *
Chris@0 30 * @var array
Chris@0 31 */
Chris@0 32 public static $modules = ['statistics', 'comment'];
Chris@0 33
Chris@0 34 protected function setUp() {
Chris@0 35 parent::setUp();
Chris@0 36
Chris@0 37 // Create a plugin instance.
Chris@0 38 $this->nodeSearch = SearchPage::load('node_search');
Chris@0 39
Chris@0 40 // Log in with sufficient privileges.
Chris@0 41 $this->drupalLogin($this->drupalCreateUser(['post comments', 'skip comment approval', 'create page content', 'administer search']));
Chris@0 42 }
Chris@0 43
Chris@0 44 public function testRankings() {
Chris@0 45 // Add a comment field.
Chris@0 46 $this->addDefaultCommentField('node', 'page');
Chris@0 47
Chris@0 48 // Build a list of the rankings to test.
Chris@0 49 $node_ranks = ['sticky', 'promote', 'relevance', 'recent', 'comments', 'views'];
Chris@0 50
Chris@0 51 // Create nodes for testing.
Chris@0 52 $nodes = [];
Chris@0 53 foreach ($node_ranks as $node_rank) {
Chris@0 54 $settings = [
Chris@0 55 'type' => 'page',
Chris@0 56 'comment' => [
Chris@0 57 ['status' => CommentItemInterface::HIDDEN],
Chris@0 58 ],
Chris@0 59 'title' => 'Drupal rocks',
Chris@0 60 'body' => [['value' => "Drupal's search rocks"]],
Chris@0 61 // Node is one day old.
Chris@0 62 'created' => REQUEST_TIME - 24 * 3600,
Chris@0 63 'sticky' => 0,
Chris@0 64 'promote' => 0,
Chris@0 65 ];
Chris@0 66 foreach ([0, 1] as $num) {
Chris@0 67 if ($num == 1) {
Chris@0 68 switch ($node_rank) {
Chris@0 69 case 'sticky':
Chris@0 70 case 'promote':
Chris@0 71 $settings[$node_rank] = 1;
Chris@0 72 break;
Chris@0 73 case 'relevance':
Chris@0 74 $settings['body'][0]['value'] .= " really rocks";
Chris@0 75 break;
Chris@0 76 case 'recent':
Chris@0 77 // Node is 1 hour hold.
Chris@0 78 $settings['created'] = REQUEST_TIME - 3600;
Chris@0 79 break;
Chris@0 80 case 'comments':
Chris@0 81 $settings['comment'][0]['status'] = CommentItemInterface::OPEN;
Chris@0 82 break;
Chris@0 83 }
Chris@0 84 }
Chris@0 85 $nodes[$node_rank][$num] = $this->drupalCreateNode($settings);
Chris@0 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 // Add a comment to one of the nodes.
Chris@0 90 $edit = [];
Chris@0 91 $edit['subject[0][value]'] = 'my comment title';
Chris@0 92 $edit['comment_body[0][value]'] = 'some random comment';
Chris@0 93 $this->drupalGet('comment/reply/node/' . $nodes['comments'][1]->id() . '/comment');
Chris@0 94 $this->drupalPostForm(NULL, $edit, t('Preview'));
Chris@0 95 $this->drupalPostForm(NULL, $edit, t('Save'));
Chris@0 96
Chris@0 97 // Enable counting of statistics.
Chris@0 98 $this->config('statistics.settings')->set('count_content_views', 1)->save();
Chris@0 99
Chris@0 100 // Simulating content views is kind of difficult in the test. Leave that
Chris@0 101 // to the Statistics module. So instead go ahead and manually update the
Chris@0 102 // counter for this node.
Chris@0 103 $nid = $nodes['views'][1]->id();
Chris@0 104 db_insert('node_counter')
Chris@0 105 ->fields(['totalcount' => 5, 'daycount' => 5, 'timestamp' => REQUEST_TIME, 'nid' => $nid])
Chris@0 106 ->execute();
Chris@0 107
Chris@0 108 // Run cron to update the search index and comment/statistics totals.
Chris@0 109 $this->cronRun();
Chris@0 110
Chris@0 111 // Test that the settings form displays the content ranking section.
Chris@0 112 $this->drupalGet('admin/config/search/pages/manage/node_search');
Chris@0 113 $this->assertText(t('Content ranking'));
Chris@0 114
Chris@0 115 // Check that all rankings are visible and set to 0.
Chris@0 116 foreach ($node_ranks as $node_rank) {
Chris@0 117 $this->assertTrue($this->xpath('//select[@id="edit-rankings-' . $node_rank . '-value"]//option[@value="0"]'), 'Select list to prioritize ' . $node_rank . ' for node ranks is visible and set to 0.');
Chris@0 118 }
Chris@0 119
Chris@0 120 // Test each of the possible rankings.
Chris@0 121 $edit = [];
Chris@0 122 foreach ($node_ranks as $node_rank) {
Chris@0 123 // Enable the ranking we are testing.
Chris@0 124 $edit['rankings[' . $node_rank . '][value]'] = 10;
Chris@0 125 $this->drupalPostForm('admin/config/search/pages/manage/node_search', $edit, t('Save search page'));
Chris@0 126 $this->drupalGet('admin/config/search/pages/manage/node_search');
Chris@0 127 $this->assertTrue($this->xpath('//select[@id="edit-rankings-' . $node_rank . '-value"]//option[@value="10"]'), 'Select list to prioritize ' . $node_rank . ' for node ranks is visible and set to 10.');
Chris@0 128
Chris@0 129 // Reload the plugin to get the up-to-date values.
Chris@0 130 $this->nodeSearch = SearchPage::load('node_search');
Chris@0 131 // Do the search and assert the results.
Chris@0 132 $this->nodeSearch->getPlugin()->setSearch('rocks', [], []);
Chris@0 133 $set = $this->nodeSearch->getPlugin()->execute();
Chris@0 134 $this->assertEqual($set[0]['node']->id(), $nodes[$node_rank][1]->id(), 'Search ranking "' . $node_rank . '" order.');
Chris@0 135
Chris@0 136 // Clear this ranking for the next test.
Chris@0 137 $edit['rankings[' . $node_rank . '][value]'] = 0;
Chris@0 138 }
Chris@0 139
Chris@0 140 // Save the final node_rank change then check that all rankings are visible
Chris@0 141 // and have been set back to 0.
Chris@0 142 $this->drupalPostForm('admin/config/search/pages/manage/node_search', $edit, t('Save search page'));
Chris@0 143 $this->drupalGet('admin/config/search/pages/manage/node_search');
Chris@0 144 foreach ($node_ranks as $node_rank) {
Chris@0 145 $this->assertTrue($this->xpath('//select[@id="edit-rankings-' . $node_rank . '-value"]//option[@value="0"]'), 'Select list to prioritize ' . $node_rank . ' for node ranks is visible and set to 0.');
Chris@0 146 }
Chris@0 147
Chris@0 148 // Try with sticky, then promoted. This is a test for issue
Chris@0 149 // https://www.drupal.org/node/771596.
Chris@0 150 $node_ranks = [
Chris@0 151 'sticky' => 10,
Chris@0 152 'promote' => 1,
Chris@0 153 'relevance' => 0,
Chris@0 154 'recent' => 0,
Chris@0 155 'comments' => 0,
Chris@0 156 'views' => 0,
Chris@0 157 ];
Chris@0 158 $configuration = $this->nodeSearch->getPlugin()->getConfiguration();
Chris@0 159 foreach ($node_ranks as $var => $value) {
Chris@0 160 $configuration['rankings'][$var] = $value;
Chris@0 161 }
Chris@0 162 $this->nodeSearch->getPlugin()->setConfiguration($configuration);
Chris@0 163 $this->nodeSearch->save();
Chris@0 164
Chris@0 165 // Do the search and assert the results. The sticky node should show up
Chris@0 166 // first, then the promoted node, then all the rest.
Chris@0 167 $this->nodeSearch->getPlugin()->setSearch('rocks', [], []);
Chris@0 168 $set = $this->nodeSearch->getPlugin()->execute();
Chris@0 169 $this->assertEqual($set[0]['node']->id(), $nodes['sticky'][1]->id(), 'Search ranking for sticky first worked.');
Chris@0 170 $this->assertEqual($set[1]['node']->id(), $nodes['promote'][1]->id(), 'Search ranking for promoted second worked.');
Chris@0 171
Chris@0 172 // Try with recent, then comments. This is a test for issues
Chris@0 173 // https://www.drupal.org/node/771596 and
Chris@0 174 // https://www.drupal.org/node/303574.
Chris@0 175 $node_ranks = [
Chris@0 176 'sticky' => 0,
Chris@0 177 'promote' => 0,
Chris@0 178 'relevance' => 0,
Chris@0 179 'recent' => 10,
Chris@0 180 'comments' => 1,
Chris@0 181 'views' => 0,
Chris@0 182 ];
Chris@0 183 $configuration = $this->nodeSearch->getPlugin()->getConfiguration();
Chris@0 184 foreach ($node_ranks as $var => $value) {
Chris@0 185 $configuration['rankings'][$var] = $value;
Chris@0 186 }
Chris@0 187 $this->nodeSearch->getPlugin()->setConfiguration($configuration);
Chris@0 188 $this->nodeSearch->save();
Chris@0 189
Chris@0 190 // Do the search and assert the results. The recent node should show up
Chris@0 191 // first, then the commented node, then all the rest.
Chris@0 192 $this->nodeSearch->getPlugin()->setSearch('rocks', [], []);
Chris@0 193 $set = $this->nodeSearch->getPlugin()->execute();
Chris@0 194 $this->assertEqual($set[0]['node']->id(), $nodes['recent'][1]->id(), 'Search ranking for recent first worked.');
Chris@0 195 $this->assertEqual($set[1]['node']->id(), $nodes['comments'][1]->id(), 'Search ranking for comments second worked.');
Chris@0 196
Chris@0 197 }
Chris@0 198
Chris@0 199 /**
Chris@0 200 * Test rankings of HTML tags.
Chris@0 201 */
Chris@0 202 public function testHTMLRankings() {
Chris@0 203 $full_html_format = FilterFormat::create([
Chris@0 204 'format' => 'full_html',
Chris@0 205 'name' => 'Full HTML',
Chris@0 206 ]);
Chris@0 207 $full_html_format->save();
Chris@0 208
Chris@0 209 // Test HTML tags with different weights.
Chris@0 210 $sorted_tags = ['h1', 'h2', 'h3', 'h4', 'a', 'h5', 'h6', 'notag'];
Chris@0 211 $shuffled_tags = $sorted_tags;
Chris@0 212
Chris@0 213 // Shuffle tags to ensure HTML tags are ranked properly.
Chris@0 214 shuffle($shuffled_tags);
Chris@0 215 $settings = [
Chris@0 216 'type' => 'page',
Chris@0 217 'title' => 'Simple node',
Chris@0 218 ];
Chris@0 219 $nodes = [];
Chris@0 220 foreach ($shuffled_tags as $tag) {
Chris@0 221 switch ($tag) {
Chris@0 222 case 'a':
Chris@0 223 $settings['body'] = [['value' => \Drupal::l('Drupal Rocks', new Url('<front>')), 'format' => 'full_html']];
Chris@0 224 break;
Chris@0 225 case 'notag':
Chris@0 226 $settings['body'] = [['value' => 'Drupal Rocks']];
Chris@0 227 break;
Chris@0 228 default:
Chris@0 229 $settings['body'] = [['value' => "<$tag>Drupal Rocks</$tag>", 'format' => 'full_html']];
Chris@0 230 break;
Chris@0 231 }
Chris@0 232 $nodes[$tag] = $this->drupalCreateNode($settings);
Chris@0 233 }
Chris@0 234
Chris@0 235 // Update the search index.
Chris@0 236 $this->nodeSearch->getPlugin()->updateIndex();
Chris@0 237 search_update_totals();
Chris@0 238
Chris@0 239 $this->nodeSearch->getPlugin()->setSearch('rocks', [], []);
Chris@0 240 // Do the search and assert the results.
Chris@0 241 $set = $this->nodeSearch->getPlugin()->execute();
Chris@0 242
Chris@0 243 // Test the ranking of each tag.
Chris@0 244 foreach ($sorted_tags as $tag_rank => $tag) {
Chris@0 245 // Assert the results.
Chris@0 246 if ($tag == 'notag') {
Chris@0 247 $this->assertEqual($set[$tag_rank]['node']->id(), $nodes[$tag]->id(), 'Search tag ranking for plain text order.');
Chris@0 248 }
Chris@0 249 else {
Chris@0 250 $this->assertEqual($set[$tag_rank]['node']->id(), $nodes[$tag]->id(), 'Search tag ranking for "&lt;' . $sorted_tags[$tag_rank] . '&gt;" order.');
Chris@0 251 }
Chris@0 252 }
Chris@0 253
Chris@0 254 // Test tags with the same weight against the sorted tags.
Chris@0 255 $unsorted_tags = ['u', 'b', 'i', 'strong', 'em'];
Chris@0 256 foreach ($unsorted_tags as $tag) {
Chris@0 257 $settings['body'] = [['value' => "<$tag>Drupal Rocks</$tag>", 'format' => 'full_html']];
Chris@0 258 $node = $this->drupalCreateNode($settings);
Chris@0 259
Chris@0 260 // Update the search index.
Chris@0 261 $this->nodeSearch->getPlugin()->updateIndex();
Chris@0 262 search_update_totals();
Chris@0 263
Chris@0 264 $this->nodeSearch->getPlugin()->setSearch('rocks', [], []);
Chris@0 265 // Do the search and assert the results.
Chris@0 266 $set = $this->nodeSearch->getPlugin()->execute();
Chris@0 267
Chris@0 268 // Ranking should always be second to last.
Chris@0 269 $set = array_slice($set, -2, 1);
Chris@0 270
Chris@0 271 // Assert the results.
Chris@0 272 $this->assertEqual($set[0]['node']->id(), $node->id(), 'Search tag ranking for "&lt;' . $tag . '&gt;" order.');
Chris@0 273
Chris@0 274 // Delete node so it doesn't show up in subsequent search results.
Chris@0 275 $node->delete();
Chris@0 276 }
Chris@0 277 }
Chris@0 278
Chris@0 279 }