[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/search/engine/solr/tests/ -> engine_test.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Solr earch engine base unit tests.
  19   *
  20   * Required params:
  21   * - define('TEST_SEARCH_SOLR_HOSTNAME', '127.0.0.1');
  22   * - define('TEST_SEARCH_SOLR_PORT', '8983');
  23   * - define('TEST_SEARCH_SOLR_INDEXNAME', 'unittest');
  24   *
  25   * Optional params:
  26   * - define('TEST_SEARCH_SOLR_USERNAME', '');
  27   * - define('TEST_SEARCH_SOLR_PASSWORD', '');
  28   * - define('TEST_SEARCH_SOLR_SSLCERT', '');
  29   * - define('TEST_SEARCH_SOLR_SSLKEY', '');
  30   * - define('TEST_SEARCH_SOLR_KEYPASSWORD', '');
  31   * - define('TEST_SEARCH_SOLR_CAINFOCERT', '');
  32   *
  33   * @package     core_search
  34   * @category    phpunit
  35   * @copyright   2015 David Monllao {@link http://www.davidmonllao.com}
  36   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  
  39  defined('MOODLE_INTERNAL') || die();
  40  
  41  global $CFG;
  42  require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
  43  require_once($CFG->dirroot . '/search/tests/fixtures/mock_search_area.php');
  44  require_once($CFG->dirroot . '/search/engine/solr/tests/fixtures/testable_engine.php');
  45  
  46  /**
  47   * Solr search engine base unit tests.
  48   *
  49   * @package     core_search
  50   * @category    phpunit
  51   * @copyright   2015 David Monllao {@link http://www.davidmonllao.com}
  52   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  53   */
  54  class search_solr_engine_testcase extends advanced_testcase {
  55  
  56      /**
  57       * @var \core_search::manager
  58       */
  59      protected $search = null;
  60  
  61      /**
  62       * @var Instace of core_search_generator.
  63       */
  64      protected $generator = null;
  65  
  66      /**
  67       * @var Instace of testable_engine.
  68       */
  69      protected $engine = null;
  70  
  71      public function setUp() {
  72          $this->resetAfterTest();
  73          set_config('enableglobalsearch', true);
  74  
  75          if (!function_exists('solr_get_version')) {
  76              $this->markTestSkipped('Solr extension is not loaded.');
  77          }
  78  
  79          if (!defined('TEST_SEARCH_SOLR_HOSTNAME') || !defined('TEST_SEARCH_SOLR_INDEXNAME') ||
  80                  !defined('TEST_SEARCH_SOLR_PORT')) {
  81              $this->markTestSkipped('Solr extension test server not set.');
  82          }
  83  
  84          set_config('server_hostname', TEST_SEARCH_SOLR_HOSTNAME, 'search_solr');
  85          set_config('server_port', TEST_SEARCH_SOLR_PORT, 'search_solr');
  86          set_config('indexname', TEST_SEARCH_SOLR_INDEXNAME, 'search_solr');
  87  
  88          if (defined('TEST_SEARCH_SOLR_USERNAME')) {
  89              set_config('server_username', TEST_SEARCH_SOLR_USERNAME, 'search_solr');
  90          }
  91  
  92          if (defined('TEST_SEARCH_SOLR_PASSWORD')) {
  93              set_config('server_password', TEST_SEARCH_SOLR_PASSWORD, 'search_solr');
  94          }
  95  
  96          if (defined('TEST_SEARCH_SOLR_SSLCERT')) {
  97              set_config('secure', true, 'search_solr');
  98              set_config('ssl_cert', TEST_SEARCH_SOLR_SSLCERT, 'search_solr');
  99          }
 100  
 101          if (defined('TEST_SEARCH_SOLR_SSLKEY')) {
 102              set_config('ssl_key', TEST_SEARCH_SOLR_SSLKEY, 'search_solr');
 103          }
 104  
 105          if (defined('TEST_SEARCH_SOLR_KEYPASSWORD')) {
 106              set_config('ssl_keypassword', TEST_SEARCH_SOLR_KEYPASSWORD, 'search_solr');
 107          }
 108  
 109          if (defined('TEST_SEARCH_SOLR_CAINFOCERT')) {
 110              set_config('ssl_cainfo', TEST_SEARCH_SOLR_CAINFOCERT, 'search_solr');
 111          }
 112  
 113          set_config('fileindexing', 1, 'search_solr');
 114  
 115          // We are only test indexing small string files, so setting this as low as we can.
 116          set_config('maxindexfilekb', 1, 'search_solr');
 117  
 118          $this->generator = self::getDataGenerator()->get_plugin_generator('core_search');
 119          $this->generator->setup();
 120  
 121          // Inject search solr engine into the testable core search as we need to add the mock
 122          // search component to it.
 123          $this->engine = new \search_solr\testable_engine();
 124          $this->search = testable_core_search::instance($this->engine);
 125          $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 126          $this->search->add_search_area($areaid, new core_mocksearch\search\mock_search_area());
 127  
 128          $this->setAdminUser();
 129  
 130          // Cleanup before doing anything on it as the index it is out of this test control.
 131          $this->search->delete_index();
 132  
 133          // Add moodle fields if they don't exist.
 134          $schema = new \search_solr\schema();
 135          $schema->setup(false);
 136      }
 137  
 138      public function tearDown() {
 139          // For unit tests before PHP 7, teardown is called even on skip. So only do our teardown if we did setup.
 140          if ($this->generator) {
 141              // Moodle DML freaks out if we don't teardown the temp table after each run.
 142              $this->generator->teardown();
 143              $this->generator = null;
 144          }
 145      }
 146  
 147      /**
 148       * Simple data provider to allow tests to be run with file indexing on and off.
 149       */
 150      public function file_indexing_provider() {
 151          return array(
 152              'file-indexing-on' => array(1),
 153              'file-indexing-off' => array(0)
 154          );
 155      }
 156  
 157      public function test_connection() {
 158          $this->assertTrue($this->engine->is_server_ready());
 159      }
 160  
 161      /**
 162       * @dataProvider file_indexing_provider
 163       */
 164      public function test_index($fileindexing) {
 165          global $DB;
 166  
 167          $this->engine->test_set_config('fileindexing', $fileindexing);
 168  
 169          $record = new \stdClass();
 170          $record->timemodified = time() - 1;
 171          $this->generator->create_record($record);
 172  
 173          // Data gets into the search engine.
 174          $this->assertTrue($this->search->index());
 175  
 176          // Not anymore as everything was already added.
 177          sleep(1);
 178          $this->assertFalse($this->search->index());
 179  
 180          $this->generator->create_record();
 181  
 182          // Indexing again once there is new data.
 183          $this->assertTrue($this->search->index());
 184      }
 185  
 186      /**
 187       * Better keep this not very strict about which or how many results are returned as may depend on solr engine config.
 188       *
 189       * @dataProvider file_indexing_provider
 190       *
 191       * @return void
 192       */
 193      public function test_search($fileindexing) {
 194          global $USER, $DB;
 195  
 196          $this->engine->test_set_config('fileindexing', $fileindexing);
 197  
 198          $this->generator->create_record();
 199          $record = new \stdClass();
 200          $record->title = "Special title";
 201          $this->generator->create_record($record);
 202  
 203          $this->search->index();
 204  
 205          $querydata = new stdClass();
 206          $querydata->q = 'message';
 207          $results = $this->search->search($querydata);
 208          $this->assertCount(2, $results);
 209  
 210          // Based on core_mocksearch\search\indexer.
 211          $this->assertEquals($USER->id, $results[0]->get('userid'));
 212          $this->assertEquals(\context_system::instance()->id, $results[0]->get('contextid'));
 213  
 214          // Do a test to make sure we aren't searching non-query fields, like areaid.
 215          $querydata->q = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 216          $this->assertCount(0, $this->search->search($querydata));
 217          $querydata->q = 'message';
 218  
 219          sleep(1);
 220          $beforeadding = time();
 221          sleep(1);
 222          $this->generator->create_record();
 223          $this->search->index();
 224  
 225          // Timestart.
 226          $querydata->timestart = $beforeadding;
 227          $this->assertCount(1, $this->search->search($querydata));
 228  
 229          // Timeend.
 230          unset($querydata->timestart);
 231          $querydata->timeend = $beforeadding;
 232          $this->assertCount(2, $this->search->search($querydata));
 233  
 234          // Title.
 235          unset($querydata->timeend);
 236          $querydata->title = 'Special title';
 237          $this->assertCount(1, $this->search->search($querydata));
 238  
 239          // Course IDs.
 240          unset($querydata->title);
 241          $querydata->courseids = array(SITEID + 1);
 242          $this->assertCount(0, $this->search->search($querydata));
 243  
 244          $querydata->courseids = array(SITEID);
 245          $this->assertCount(3, $this->search->search($querydata));
 246  
 247          // Now try some area-id combinations.
 248          unset($querydata->courseids);
 249          $forumpostareaid = \core_search\manager::generate_areaid('mod_forum', 'post');
 250          $mockareaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 251  
 252          $querydata->areaids = array($forumpostareaid);
 253          $this->assertCount(0, $this->search->search($querydata));
 254  
 255          $querydata->areaids = array($forumpostareaid, $mockareaid);
 256          $this->assertCount(3, $this->search->search($querydata));
 257  
 258          $querydata->areaids = array($mockareaid);
 259          $this->assertCount(3, $this->search->search($querydata));
 260  
 261          $querydata->areaids = array();
 262          $this->assertCount(3, $this->search->search($querydata));
 263  
 264          // Check that index contents get updated.
 265          $this->generator->delete_all();
 266          $this->search->index(true);
 267          unset($querydata->title);
 268          $querydata->q = '*';
 269          $this->assertCount(0, $this->search->search($querydata));
 270      }
 271  
 272      /**
 273       * @dataProvider file_indexing_provider
 274       */
 275      public function test_delete($fileindexing) {
 276          $this->engine->test_set_config('fileindexing', $fileindexing);
 277  
 278          $this->generator->create_record();
 279          $this->generator->create_record();
 280          $this->search->index();
 281  
 282          $querydata = new stdClass();
 283          $querydata->q = 'message';
 284  
 285          $this->assertCount(2, $this->search->search($querydata));
 286  
 287          $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 288          $this->search->delete_index($areaid);
 289          $this->assertCount(0, $this->search->search($querydata));
 290      }
 291  
 292      /**
 293       * @dataProvider file_indexing_provider
 294       */
 295      public function test_alloweduserid($fileindexing) {
 296          $this->engine->test_set_config('fileindexing', $fileindexing);
 297  
 298          $area = new core_mocksearch\search\mock_search_area();
 299  
 300          $record = $this->generator->create_record();
 301  
 302          // Get the doc and insert the default doc.
 303          $doc = $area->get_document($record);
 304          $this->engine->add_document($doc);
 305  
 306          $users = array();
 307          $users[] = $this->getDataGenerator()->create_user();
 308          $users[] = $this->getDataGenerator()->create_user();
 309          $users[] = $this->getDataGenerator()->create_user();
 310  
 311          // Add a record that only user 100 can see.
 312          $originalid = $doc->get('id');
 313  
 314          // Now add a custom doc for each user.
 315          foreach ($users as $user) {
 316              $doc = $area->get_document($record);
 317              $doc->set('id', $originalid.'-'.$user->id);
 318              $doc->set('owneruserid', $user->id);
 319              $this->engine->add_document($doc);
 320          }
 321  
 322          $this->engine->area_index_complete($area->get_area_id());
 323  
 324          $querydata = new stdClass();
 325          $querydata->q = 'message';
 326          $querydata->title = $doc->get('title');
 327  
 328          // We are going to go through each user and see if they get the original and the owned doc.
 329          foreach ($users as $user) {
 330              $this->setUser($user);
 331  
 332              $results = $this->search->search($querydata);
 333              $this->assertCount(2, $results);
 334  
 335              $owned = 0;
 336              $notowned = 0;
 337  
 338              // We don't know what order we will get the results in, so we are doing this.
 339              foreach ($results as $result) {
 340                  $owneruserid = $result->get('owneruserid');
 341                  if (empty($owneruserid)) {
 342                      $notowned++;
 343                      $this->assertEquals(0, $owneruserid);
 344                      $this->assertEquals($originalid, $result->get('id'));
 345                  } else {
 346                      $owned++;
 347                      $this->assertEquals($user->id, $owneruserid);
 348                      $this->assertEquals($originalid.'-'.$user->id, $result->get('id'));
 349                  }
 350              }
 351  
 352              $this->assertEquals(1, $owned);
 353              $this->assertEquals(1, $notowned);
 354          }
 355  
 356          // Now test a user with no owned results.
 357          $otheruser = $this->getDataGenerator()->create_user();
 358          $this->setUser($otheruser);
 359  
 360          $results = $this->search->search($querydata);
 361          $this->assertCount(1, $results);
 362  
 363          $this->assertEquals(0, $results[0]->get('owneruserid'));
 364          $this->assertEquals($originalid, $results[0]->get('id'));
 365      }
 366  
 367      /**
 368       * @dataProvider file_indexing_provider
 369       */
 370      public function test_highlight($fileindexing) {
 371          global $PAGE;
 372  
 373          $this->engine->test_set_config('fileindexing', $fileindexing);
 374  
 375          $this->generator->create_record();
 376          $this->search->index();
 377  
 378          $querydata = new stdClass();
 379          $querydata->q = 'message';
 380  
 381          $results = $this->search->search($querydata);
 382          $this->assertCount(1, $results);
 383  
 384          $result = reset($results);
 385  
 386          $regex = '|'.\search_solr\engine::HIGHLIGHT_START.'message'.\search_solr\engine::HIGHLIGHT_END.'|';
 387          $this->assertRegExp($regex, $result->get('content'));
 388  
 389          $searchrenderer = $PAGE->get_renderer('core_search');
 390          $exported = $result->export_for_template($searchrenderer);
 391  
 392          $regex = '|<span class="highlight">message</span>|';
 393          $this->assertRegExp($regex, $exported['content']);
 394      }
 395  
 396      public function test_index_file() {
 397          // Very simple test.
 398          $file = $this->generator->create_file();
 399  
 400          $record = new \stdClass();
 401          $record->attachfileids = array($file->get_id());
 402          $this->generator->create_record($record);
 403  
 404          $this->search->index();
 405          $querydata = new stdClass();
 406          $querydata->q = '"File contents"';
 407  
 408          $this->assertCount(1, $this->search->search($querydata));
 409      }
 410  
 411      public function test_reindexing_files() {
 412          // Get area to work with.
 413          $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 414          $area = \core_search\manager::get_search_area($areaid);
 415  
 416          $record = $this->generator->create_record();
 417  
 418          $doc = $area->get_document($record);
 419  
 420          // Now we are going to make some files.
 421          $fs = get_file_storage();
 422          $syscontext = \context_system::instance();
 423  
 424          $files = array();
 425  
 426          $filerecord = new \stdClass();
 427          // We make enough so that we pass the 500 files threashold. That is the boundary when getting files.
 428          $boundary = 500;
 429          $top = (int)($boundary * 1.1);
 430          for ($i = 0; $i < $top; $i++) {
 431              $filerecord->filename  = 'searchfile'.$i;
 432              $filerecord->content = 'Some FileContents'.$i;
 433              $file = $this->generator->create_file($filerecord);
 434              $doc->add_stored_file($file);
 435              $files[] = $file;
 436          }
 437  
 438          // Add the doc with lots of files, then commit.
 439          $this->engine->add_document($doc, true);
 440          $this->engine->area_index_complete($area->get_area_id());
 441  
 442          // Indexes we are going to check. 0 means we will delete, 1 means we will keep.
 443          $checkfiles = array(
 444              0 => 0,                        // Check the begining of the set.
 445              1 => 1,
 446              2 => 0,
 447              ($top - 3) => 0,               // Check the end of the set.
 448              ($top - 2) => 1,
 449              ($top - 1) => 0,
 450              ($boundary - 2) => 0,          // Check at the boundary between fetch groups.
 451              ($boundary - 1) => 0,
 452              $boundary => 0,
 453              ($boundary + 1) => 0,
 454              ((int)($boundary * 0.5)) => 1, // Make sure we keep some middle ones.
 455              ((int)($boundary * 1.05)) => 1
 456          );
 457  
 458          $querydata = new stdClass();
 459  
 460          // First, check that all the files are currently there.
 461          foreach ($checkfiles as $key => $unused) {
 462              $querydata->q = 'FileContents'.$key;
 463              $this->assertCount(1, $this->search->search($querydata));
 464              $querydata->q = 'searchfile'.$key;
 465              $this->assertCount(1, $this->search->search($querydata));
 466          }
 467  
 468          // Remove the files we want removed from the files array.
 469          foreach ($checkfiles as $key => $keep) {
 470              if (!$keep) {
 471                  unset($files[$key]);
 472              }
 473          }
 474  
 475          // And make us a new file to add.
 476          $filerecord->filename  = 'searchfileNew';
 477          $filerecord->content  = 'Some FileContentsNew';
 478          $files[] = $this->generator->create_file($filerecord);
 479          $checkfiles['New'] = 1;
 480  
 481          $doc = $area->get_document($record);
 482          foreach($files as $file) {
 483              $doc->add_stored_file($file);
 484          }
 485  
 486          // Reindex the document with the changed files.
 487          $this->engine->add_document($doc, true);
 488          $this->engine->area_index_complete($area->get_area_id());
 489  
 490          // Go through our check array, and see if the file is there or not.
 491          foreach ($checkfiles as $key => $keep) {
 492              $querydata->q = 'FileContents'.$key;
 493              $this->assertCount($keep, $this->search->search($querydata));
 494              $querydata->q = 'searchfile'.$key;
 495              $this->assertCount($keep, $this->search->search($querydata));
 496          }
 497  
 498          // Now check that we get one result when we search from something in all of them.
 499          $querydata->q = 'Some';
 500          $this->assertCount(1, $this->search->search($querydata));
 501      }
 502  
 503      /**
 504       * Test indexing a file we don't consider indexable.
 505       */
 506      public function test_index_filtered_file() {
 507          // Get area to work with.
 508          $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
 509          $area = \core_search\manager::get_search_area($areaid);
 510  
 511          // Get a single record to make a doc from.
 512          $record = $this->generator->create_record();
 513  
 514          $doc = $area->get_document($record);
 515  
 516          // Now we are going to make some files.
 517          $fs = get_file_storage();
 518          $syscontext = \context_system::instance();
 519  
 520          // We need to make a file greater than 1kB in size, which is the lowest filter size.
 521          $filerecord = new \stdClass();
 522          $filerecord->filename = 'largefile';
 523          $filerecord->content = 'Some LargeFindContent to find.';
 524          for ($i = 0; $i < 200; $i++) {
 525              $filerecord->content .= ' The quick brown fox jumps over the lazy dog.';
 526          }
 527  
 528          $this->assertGreaterThan(1024, strlen($filerecord->content));
 529  
 530          $file = $this->generator->create_file($filerecord);
 531          $doc->add_stored_file($file);
 532  
 533          $filerecord->filename = 'smallfile';
 534          $filerecord->content = 'Some SmallFindContent to find.';
 535          $file = $this->generator->create_file($filerecord);
 536          $doc->add_stored_file($file);
 537  
 538          $this->engine->add_document($doc, true);
 539          $this->engine->area_index_complete($area->get_area_id());
 540  
 541          $querydata = new stdClass();
 542          // We shouldn't be able to find the large file contents.
 543          $querydata->q = 'LargeFindContent';
 544          $this->assertCount(0, $this->search->search($querydata));
 545  
 546          // But we should be able to find the filename.
 547          $querydata->q = 'largefile';
 548          $this->assertCount(1, $this->search->search($querydata));
 549  
 550          // We should be able to find the small file contents.
 551          $querydata->q = 'SmallFindContent';
 552          $this->assertCount(1, $this->search->search($querydata));
 553  
 554          // And we should be able to find the filename.
 555          $querydata->q = 'smallfile';
 556          $this->assertCount(1, $this->search->search($querydata));
 557      }
 558  
 559      public function test_delete_by_id() {
 560          // First get files in the index.
 561          $file = $this->generator->create_file();
 562          $record = new \stdClass();
 563          $record->attachfileids = array($file->get_id());
 564          $this->generator->create_record($record);
 565          $this->generator->create_record($record);
 566          $this->search->index();
 567  
 568          $querydata = new stdClass();
 569  
 570          // Then search to make sure they are there.
 571          $querydata->q = '"File contents"';
 572          $results = $this->search->search($querydata);
 573          $this->assertCount(2, $results);
 574  
 575          $first = reset($results);
 576          $deleteid = $first->get('id');
 577  
 578          $this->engine->delete_by_id($deleteid);
 579  
 580          // Check that we don't get a result for it anymore.
 581          $results = $this->search->search($querydata);
 582          $this->assertCount(1, $results);
 583          $result = reset($results);
 584          $this->assertNotEquals($deleteid, $result->get('id'));
 585      }
 586  
 587      /**
 588       * Test that expected results are returned, even with low check_access success rate.
 589       *
 590       * @dataProvider file_indexing_provider
 591       */
 592      public function test_solr_filling($fileindexing) {
 593          $this->engine->test_set_config('fileindexing', $fileindexing);
 594  
 595          $user1 = self::getDataGenerator()->create_user();
 596          $user2 = self::getDataGenerator()->create_user();
 597  
 598          // We are going to create a bunch of records that user 1 can see with 2 keywords.
 599          // Then we are going to create a bunch for user 2 with only 1 of the keywords.
 600          // If user 2 searches for both keywords, solr will return all of the user 1 results, then the user 2 results.
 601          // This is because the user 1 results will match 2 keywords, while the others will match only 1.
 602  
 603          $record = new \stdClass();
 604  
 605          // First create a bunch of records for user 1 to see.
 606          $record->denyuserids = array($user2->id);
 607          $record->content = 'Something1 Something2';
 608          $maxresults = (int)(\core_search\manager::MAX_RESULTS * .75);
 609          for ($i = 0; $i < $maxresults; $i++) {
 610              $this->generator->create_record($record);
 611          }
 612  
 613          // Then create a bunch of records for user 2 to see.
 614          $record->denyuserids = array($user1->id);
 615          $record->content = 'Something1';
 616          for ($i = 0; $i < $maxresults; $i++) {
 617              $this->generator->create_record($record);
 618          }
 619  
 620          $this->search->index();
 621  
 622          // Check that user 1 sees all their results.
 623          $this->setUser($user1);
 624          $querydata = new stdClass();
 625          $querydata->q = 'Something1 Something2';
 626          $results = $this->search->search($querydata);
 627          $this->assertCount($maxresults, $results);
 628  
 629          // Check that user 2 will see theirs, even though they may be crouded out.
 630          $this->setUser($user2);
 631          $results = $this->search->search($querydata);
 632          $this->assertCount($maxresults, $results);
 633      }
 634  
 635      /**
 636       * Create 40 docs, that will be return from Solr in 10 hidden, 10 visible, 10 hidden, 10 visible if you query for:
 637       * Something1 Something2 Something3 Something4, with the specified user set.
 638       */
 639      protected function setup_user_hidden_docs($user) {
 640          // These results will come first, and will not be visible by the user.
 641          $record = new \stdClass();
 642          $record->denyuserids = array($user->id);
 643          $record->content = 'Something1 Something2 Something3 Something4';
 644          for ($i = 0; $i < 10; $i++) {
 645              $this->generator->create_record($record);
 646          }
 647  
 648          // These results will come second, and will  be visible by the user.
 649          unset($record->denyuserids);
 650          $record->content = 'Something1 Something2 Something3';
 651          for ($i = 0; $i < 10; $i++) {
 652              $this->generator->create_record($record);
 653          }
 654  
 655          // These results will come third, and will not be visible by the user.
 656          $record->denyuserids = array($user->id);
 657          $record->content = 'Something1 Something2';
 658          for ($i = 0; $i < 10; $i++) {
 659              $this->generator->create_record($record);
 660          }
 661  
 662          // These results will come fourth, and will be visible by the user.
 663          unset($record->denyuserids);
 664          $record->content = 'Something1 ';
 665          for ($i = 0; $i < 10; $i++) {
 666              $this->generator->create_record($record);
 667          }
 668      }
 669  
 670      /**
 671       * Test that counts are what we expect.
 672       *
 673       * @dataProvider file_indexing_provider
 674       */
 675      public function test_get_query_total_count($fileindexing) {
 676          $this->engine->test_set_config('fileindexing', $fileindexing);
 677  
 678          $user = self::getDataGenerator()->create_user();
 679          $this->setup_user_hidden_docs($user);
 680          $this->search->index();
 681  
 682          $this->setUser($user);
 683          $querydata = new stdClass();
 684          $querydata->q = 'Something1 Something2 Something3 Something4';
 685  
 686          // In this first set, it should have determined the first 10 of 40 are bad, so there could be up to 30 left.
 687          $results = $this->engine->execute_query($querydata, true, 5);
 688          $this->assertEquals(30, $this->engine->get_query_total_count());
 689          $this->assertCount(5, $results);
 690  
 691          // To get to 15, it has to process the first 10 that are bad, 10 that are good, 10 that are bad, then 5 that are good.
 692          // So we now know 20 are bad out of 40.
 693          $results = $this->engine->execute_query($querydata, true, 15);
 694          $this->assertEquals(20, $this->engine->get_query_total_count());
 695          $this->assertCount(15, $results);
 696  
 697          // Try to get more then all, make sure we still see 20 count and 20 returned.
 698          $results = $this->engine->execute_query($querydata, true, 30);
 699          $this->assertEquals(20, $this->engine->get_query_total_count());
 700          $this->assertCount(20, $results);
 701      }
 702  
 703      /**
 704       * Test that paged results are what we expect.
 705       *
 706       * @dataProvider file_indexing_provider
 707       */
 708      public function test_manager_paged_search($fileindexing) {
 709          $this->engine->test_set_config('fileindexing', $fileindexing);
 710  
 711          $user = self::getDataGenerator()->create_user();
 712          $this->setup_user_hidden_docs($user);
 713          $this->search->index();
 714  
 715          // Check that user 1 sees all their results.
 716          $this->setUser($user);
 717          $querydata = new stdClass();
 718          $querydata->q = 'Something1 Something2 Something3 Something4';
 719  
 720          // On this first page, it should have determined the first 10 of 40 are bad, so there could be up to 30 left.
 721          $results = $this->search->paged_search($querydata, 0);
 722          $this->assertEquals(30, $results->totalcount);
 723          $this->assertCount(10, $results->results);
 724          $this->assertEquals(0, $results->actualpage);
 725  
 726          // On the second page, it should have found the next 10 bad ones, so we no know there are only 20 total.
 727          $results = $this->search->paged_search($querydata, 1);
 728          $this->assertEquals(20, $results->totalcount);
 729          $this->assertCount(10, $results->results);
 730          $this->assertEquals(1, $results->actualpage);
 731  
 732          // Try to get an additional page - we should get back page 1 results, since that is the last page with valid results.
 733          $results = $this->search->paged_search($querydata, 2);
 734          $this->assertEquals(20, $results->totalcount);
 735          $this->assertCount(10, $results->results);
 736          $this->assertEquals(1, $results->actualpage);
 737      }
 738  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1