2016-01-26 21:18:27 +00:00
|
|
|
<?php
|
2017-04-19 19:37:35 +00:00
|
|
|
|
2016-04-03 08:37:11 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2017-04-19 19:37:35 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
2016-04-03 08:37:11 +00:00
|
|
|
|
2016-01-26 21:18:27 +00:00
|
|
|
/**
|
|
|
|
|
* @group Search
|
|
|
|
|
* @group Database
|
|
|
|
|
*/
|
|
|
|
|
class SearchEnginePrefixTest extends MediaWikiLangTestCase {
|
2016-03-03 07:16:53 +00:00
|
|
|
private $originalHandlers;
|
2016-01-26 21:18:27 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var SearchEngine
|
|
|
|
|
*/
|
|
|
|
|
private $search;
|
|
|
|
|
|
2016-03-07 17:26:25 +00:00
|
|
|
public function addDBDataOnce() {
|
2016-01-26 21:18:27 +00:00
|
|
|
if ( !$this->isWikitextNS( NS_MAIN ) ) {
|
|
|
|
|
// tests are skipped if NS_MAIN is not wikitext
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->insertPage( 'Sandbox' );
|
|
|
|
|
$this->insertPage( 'Bar' );
|
|
|
|
|
$this->insertPage( 'Example' );
|
|
|
|
|
$this->insertPage( 'Example Bar' );
|
|
|
|
|
$this->insertPage( 'Example Foo' );
|
|
|
|
|
$this->insertPage( 'Example Foo/Bar' );
|
|
|
|
|
$this->insertPage( 'Example/Baz' );
|
2017-05-18 20:29:13 +00:00
|
|
|
$this->insertPage( 'Sample' );
|
|
|
|
|
$this->insertPage( 'Sample Ban' );
|
|
|
|
|
$this->insertPage( 'Sample Eat' );
|
|
|
|
|
$this->insertPage( 'Sample Who' );
|
|
|
|
|
$this->insertPage( 'Sample Zoo' );
|
2016-01-26 21:18:27 +00:00
|
|
|
$this->insertPage( 'Redirect test', '#REDIRECT [[Redirect Test]]' );
|
|
|
|
|
$this->insertPage( 'Redirect Test' );
|
|
|
|
|
$this->insertPage( 'Redirect Test Worse Result' );
|
|
|
|
|
$this->insertPage( 'Redirect test2', '#REDIRECT [[Redirect Test2]]' );
|
|
|
|
|
$this->insertPage( 'Redirect TEST2', '#REDIRECT [[Redirect Test2]]' );
|
|
|
|
|
$this->insertPage( 'Redirect Test2' );
|
|
|
|
|
$this->insertPage( 'Redirect Test2 Worse Result' );
|
|
|
|
|
|
|
|
|
|
$this->insertPage( 'Talk:Sandbox' );
|
|
|
|
|
$this->insertPage( 'Talk:Example' );
|
|
|
|
|
|
|
|
|
|
$this->insertPage( 'User:Example' );
|
2017-12-14 01:03:20 +00:00
|
|
|
$this->insertPage( 'Barcelona' );
|
|
|
|
|
$this->insertPage( 'Barbara' );
|
|
|
|
|
$this->insertPage( 'External' );
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function setUp() {
|
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
|
|
if ( !$this->isWikitextNS( NS_MAIN ) ) {
|
|
|
|
|
$this->markTestSkipped( 'Main namespace does not support wikitext.' );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Avoid special pages from extensions interferring with the tests
|
2016-03-03 07:16:53 +00:00
|
|
|
$this->setMwGlobals( [
|
|
|
|
|
'wgSpecialPages' => [],
|
|
|
|
|
'wgHooks' => [],
|
|
|
|
|
] );
|
|
|
|
|
|
2016-04-03 08:37:11 +00:00
|
|
|
$this->search = MediaWikiServices::getInstance()->newSearchEngine();
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->search->setNamespaces( [] );
|
2016-03-03 07:16:53 +00:00
|
|
|
|
2018-01-13 00:02:09 +00:00
|
|
|
$this->originalHandlers = TestingAccessWrapper::newFromClass( Hooks::class )->handlers;
|
|
|
|
|
TestingAccessWrapper::newFromClass( Hooks::class )->handlers = [];
|
2016-03-03 07:16:53 +00:00
|
|
|
|
2018-08-07 10:58:31 +00:00
|
|
|
$this->overrideMwServices();
|
2016-03-03 07:16:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function tearDown() {
|
|
|
|
|
parent::tearDown();
|
|
|
|
|
|
2018-01-13 00:02:09 +00:00
|
|
|
TestingAccessWrapper::newFromClass( Hooks::class )->handlers = $this->originalHandlers;
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
2016-02-17 10:31:52 +00:00
|
|
|
protected function searchProvision( array $results = null ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
if ( $results === null ) {
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->setMwGlobals( 'wgHooks', [] );
|
2016-01-26 21:18:27 +00:00
|
|
|
} else {
|
2016-02-17 09:09:32 +00:00
|
|
|
$this->setMwGlobals( 'wgHooks', [
|
|
|
|
|
'PrefixSearchBackend' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
|
|
|
|
|
$srchres = $results;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] );
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideSearch() {
|
2016-02-17 09:09:32 +00:00
|
|
|
return [
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Empty string',
|
|
|
|
|
'query' => '',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Main namespace with title prefix',
|
2017-05-18 20:29:13 +00:00
|
|
|
'query' => 'Sa',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2017-05-18 20:29:13 +00:00
|
|
|
'Sample',
|
|
|
|
|
'Sample Ban',
|
|
|
|
|
'Sample Eat',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
// Third result when testing offset
|
2016-02-17 09:09:32 +00:00
|
|
|
'offsetresult' => [
|
2017-05-18 20:29:13 +00:00
|
|
|
'Sample Who',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Talk namespace prefix',
|
|
|
|
|
'query' => 'Talk:',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Talk:Example',
|
|
|
|
|
'Talk:Sandbox',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'User namespace prefix',
|
|
|
|
|
'query' => 'User:',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'User:Example',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special namespace prefix',
|
|
|
|
|
'query' => 'Special:',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special:ActiveUsers',
|
|
|
|
|
'Special:AllMessages',
|
2016-11-29 21:54:15 +00:00
|
|
|
'Special:AllMyUploads',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
// Third result when testing offset
|
2016-02-17 09:09:32 +00:00
|
|
|
'offsetresult' => [
|
2016-11-29 21:54:15 +00:00
|
|
|
'Special:AllPages',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special namespace with prefix',
|
|
|
|
|
'query' => 'Special:Un',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special:Unblock',
|
|
|
|
|
'Special:UncategorizedCategories',
|
|
|
|
|
'Special:UncategorizedFiles',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
// Third result when testing offset
|
2016-02-17 09:09:32 +00:00
|
|
|
'offsetresult' => [
|
2016-11-29 21:54:15 +00:00
|
|
|
'Special:UncategorizedPages',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special page name',
|
|
|
|
|
'query' => 'Special:EditWatchlist',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special:EditWatchlist',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special page subpages',
|
|
|
|
|
'query' => 'Special:EditWatchlist/',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special:EditWatchlist/clear',
|
|
|
|
|
'Special:EditWatchlist/raw',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special page subpages with prefix',
|
|
|
|
|
'query' => 'Special:EditWatchlist/cl',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Special:EditWatchlist/clear',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
];
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideSearch
|
|
|
|
|
* @covers SearchEngine::defaultPrefixSearch
|
|
|
|
|
*/
|
2016-02-17 10:31:52 +00:00
|
|
|
public function testSearch( array $case ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
$this->search->setLimitOffset( 3 );
|
|
|
|
|
$results = $this->search->defaultPrefixSearch( $case['query'] );
|
2017-06-26 16:35:31 +00:00
|
|
|
$results = array_map( function ( Title $t ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
return $t->getPrefixedText();
|
|
|
|
|
}, $results );
|
2017-05-18 20:29:13 +00:00
|
|
|
|
2016-01-26 21:18:27 +00:00
|
|
|
$this->assertEquals(
|
|
|
|
|
$case['results'],
|
|
|
|
|
$results,
|
|
|
|
|
$case[0]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideSearch
|
|
|
|
|
* @covers SearchEngine::defaultPrefixSearch
|
|
|
|
|
*/
|
2016-02-17 10:31:52 +00:00
|
|
|
public function testSearchWithOffset( array $case ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
$this->search->setLimitOffset( 3, 1 );
|
|
|
|
|
$results = $this->search->defaultPrefixSearch( $case['query'] );
|
2017-06-26 16:35:31 +00:00
|
|
|
$results = array_map( function ( Title $t ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
return $t->getPrefixedText();
|
|
|
|
|
}, $results );
|
|
|
|
|
|
|
|
|
|
// We don't expect the first result when offsetting
|
|
|
|
|
array_shift( $case['results'] );
|
|
|
|
|
// And sometimes we expect a different last result
|
|
|
|
|
$expected = isset( $case['offsetresult'] ) ?
|
|
|
|
|
array_merge( $case['results'], $case['offsetresult'] ) :
|
|
|
|
|
$case['results'];
|
|
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
$expected,
|
|
|
|
|
$results,
|
|
|
|
|
$case[0]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideSearchBackend() {
|
2016-02-17 09:09:32 +00:00
|
|
|
return [
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Simple case',
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Bar',
|
|
|
|
|
'Barcelona',
|
|
|
|
|
'Barbara',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'Bar',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Bar',
|
|
|
|
|
'Barcelona',
|
|
|
|
|
'Barbara',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2017-12-14 01:03:20 +00:00
|
|
|
'Exact match not in first result should be moved to the first result (T72958)',
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Barcelona',
|
|
|
|
|
'Bar',
|
|
|
|
|
'Barbara',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'Bar',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Bar',
|
|
|
|
|
'Barcelona',
|
|
|
|
|
'Barbara',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2017-12-14 01:03:20 +00:00
|
|
|
'Exact match missing from results should be added as first result (T72958)',
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Barcelona',
|
|
|
|
|
'Barbara',
|
|
|
|
|
'Bart',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'Bar',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Bar',
|
|
|
|
|
'Barcelona',
|
|
|
|
|
'Barbara',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2017-12-14 01:03:20 +00:00
|
|
|
'Exact match missing and not existing pages should be dropped',
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'Exile',
|
|
|
|
|
'Exist',
|
|
|
|
|
'External',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'Ex',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
'External',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
"Exact match shouldn't override already found match if " .
|
|
|
|
|
"exact is redirect and found isn't",
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Target of the exact match is low in the list
|
|
|
|
|
'Redirect Test Worse Result',
|
|
|
|
|
'Redirect Test',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'redirect test',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Redirect target is pulled up and exact match isn't added
|
|
|
|
|
'Redirect Test',
|
|
|
|
|
'Redirect Test Worse Result',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
"Exact match shouldn't override already found match if " .
|
|
|
|
|
"both exact match and found match are redirect",
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Another redirect to the same target as the exact match
|
|
|
|
|
// is low in the list
|
|
|
|
|
'Redirect Test2 Worse Result',
|
|
|
|
|
'Redirect test2',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'redirect TEST2',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Found redirect is pulled to the top and exact match isn't
|
|
|
|
|
// added
|
|
|
|
|
'Redirect test2',
|
|
|
|
|
'Redirect Test2 Worse Result',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
|
|
|
|
[ [
|
2016-01-26 21:18:27 +00:00
|
|
|
"Exact match should override any already found matches that " .
|
|
|
|
|
"are redirects to it",
|
2016-02-17 09:09:32 +00:00
|
|
|
'provision' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Another redirect to the same target as the exact match
|
|
|
|
|
// is low in the list
|
|
|
|
|
'Redirect Test Worse Result',
|
|
|
|
|
'Redirect test',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
2016-01-26 21:18:27 +00:00
|
|
|
'query' => 'Redirect Test',
|
2016-02-17 09:09:32 +00:00
|
|
|
'results' => [
|
2016-01-26 21:18:27 +00:00
|
|
|
// Found redirect is pulled to the top and exact match isn't
|
|
|
|
|
// added
|
|
|
|
|
'Redirect Test',
|
|
|
|
|
'Redirect Test Worse Result',
|
|
|
|
|
'Redirect test',
|
2016-02-17 09:09:32 +00:00
|
|
|
],
|
|
|
|
|
] ],
|
2017-12-19 22:19:49 +00:00
|
|
|
[ [
|
|
|
|
|
"Extra results must not be returned",
|
|
|
|
|
'provision' => [
|
|
|
|
|
'Example',
|
|
|
|
|
'Example Bar',
|
|
|
|
|
'Example Foo',
|
|
|
|
|
'Example Foo/Bar'
|
|
|
|
|
],
|
|
|
|
|
'query' => 'foo',
|
|
|
|
|
'results' => [
|
|
|
|
|
'Example',
|
|
|
|
|
'Example Bar',
|
|
|
|
|
'Example Foo',
|
|
|
|
|
],
|
|
|
|
|
] ],
|
2016-02-17 09:09:32 +00:00
|
|
|
];
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideSearchBackend
|
|
|
|
|
* @covers PrefixSearch::searchBackend
|
|
|
|
|
*/
|
2016-02-17 10:31:52 +00:00
|
|
|
public function testSearchBackend( array $case ) {
|
2017-12-19 22:19:49 +00:00
|
|
|
$search = $this->mockSearchWithResults( $case['provision'] );
|
2016-01-26 21:18:27 +00:00
|
|
|
$results = $search->completionSearch( $case['query'] );
|
|
|
|
|
|
2017-06-26 16:35:31 +00:00
|
|
|
$results = $results->map( function ( SearchSuggestion $s ) {
|
2016-01-26 21:18:27 +00:00
|
|
|
return $s->getText();
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
$case['results'],
|
|
|
|
|
$results,
|
|
|
|
|
$case[0]
|
|
|
|
|
);
|
|
|
|
|
}
|
2017-12-19 22:19:49 +00:00
|
|
|
|
|
|
|
|
public function paginationProvider() {
|
|
|
|
|
$res = [ 'Example', 'Example Bar', 'Example Foo', 'Example Foo/Bar' ];
|
|
|
|
|
return [
|
|
|
|
|
'With less than requested results no pagination' => [
|
|
|
|
|
false, array_slice( $res, 0, 2 ),
|
|
|
|
|
],
|
|
|
|
|
'With same as requested results no pagination' => [
|
|
|
|
|
false, array_slice( $res, 0, 3 ),
|
|
|
|
|
],
|
|
|
|
|
'With extra result returned offer pagination' => [
|
|
|
|
|
true, $res,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider paginationProvider
|
|
|
|
|
*/
|
|
|
|
|
public function testPagination( $hasMoreResults, $provision ) {
|
|
|
|
|
$search = $this->mockSearchWithResults( $provision );
|
|
|
|
|
$results = $search->completionSearch( 'irrelevant' );
|
|
|
|
|
|
|
|
|
|
$this->assertEquals( $hasMoreResults, $results->hasMoreResults() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function mockSearchWithResults( $titleStrings, $limit = 3 ) {
|
|
|
|
|
$search = $stub = $this->getMockBuilder( SearchEngine::class )
|
|
|
|
|
->setMethods( [ 'completionSearchBackend' ] )->getMock();
|
|
|
|
|
|
|
|
|
|
$return = SearchSuggestionSet::fromStrings( $titleStrings );
|
|
|
|
|
|
|
|
|
|
$search->expects( $this->any() )
|
|
|
|
|
->method( 'completionSearchBackend' )
|
|
|
|
|
->will( $this->returnValue( $return ) );
|
|
|
|
|
|
|
|
|
|
$search->setLimitOffset( $limit );
|
|
|
|
|
return $search;
|
|
|
|
|
}
|
2016-01-26 21:18:27 +00:00
|
|
|
}
|