Prefix search attempts to find exact matches to the user's query that aren't returned by plugins. In some cases, like when the exact match is a redirect and the target of the redirect is also in the search results, it would result in multiple results in prefix search going the same place. This looks really silly when the top hit is "Barack obama" (a redirect) and the next one is "Barack Obama" (the target of the redirect). This handles a bunch of cases to do with redirects in the matches and when the exact match is a redirect. Bug: 736731 Change-Id: I49fe1ccec84bd5d1f44c6b91b260abf50f2cc3a1
272 lines
6.3 KiB
PHP
272 lines
6.3 KiB
PHP
<?php
|
|
/**
|
|
* @group Search
|
|
* @group Database
|
|
*/
|
|
class PrefixSearchTest extends MediaWikiLangTestCase {
|
|
|
|
protected function setUp() {
|
|
parent::setUp();
|
|
|
|
if ( !$this->isWikitextNS( NS_MAIN ) ) {
|
|
$this->markTestSkipped( 'Main namespace does not support wikitext.' );
|
|
}
|
|
|
|
$this->insertPages();
|
|
|
|
// Avoid special pages from extensions interferring with the tests
|
|
$this->setMwGlobals( 'wgSpecialPages', array() );
|
|
}
|
|
|
|
protected function searchProvision( Array $results = null ) {
|
|
if ( $results === null ) {
|
|
$this->setMwGlobals( 'wgHooks', array() );
|
|
} else {
|
|
$this->setMwGlobals( 'wgHooks', array(
|
|
'PrefixSearchBackend' => array(
|
|
function ( $namespaces, $search, $limit, &$srchres ) use ( $results ) {
|
|
$srchres = $results;
|
|
return false;
|
|
}
|
|
),
|
|
) );
|
|
}
|
|
}
|
|
|
|
public function insertPages() {
|
|
$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' );
|
|
$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' );
|
|
}
|
|
|
|
public static function provideSearch() {
|
|
return array(
|
|
array( array(
|
|
'Empty string',
|
|
'query' => '',
|
|
'results' => array(),
|
|
) ),
|
|
array( array(
|
|
'Main namespace with title prefix',
|
|
'query' => 'Ex',
|
|
'results' => array(
|
|
'Example',
|
|
'Example/Baz',
|
|
'Example Bar',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Talk namespace prefix',
|
|
'query' => 'Talk:',
|
|
'results' => array(
|
|
'Talk:Example',
|
|
'Talk:Sandbox',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'User namespace prefix',
|
|
'query' => 'User:',
|
|
'results' => array(
|
|
'User:Example',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Special namespace prefix',
|
|
'query' => 'Special:',
|
|
'results' => array(
|
|
'Special:ActiveUsers',
|
|
'Special:AllMessages',
|
|
'Special:AllMyFiles',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Special namespace with prefix',
|
|
'query' => 'Special:Un',
|
|
'results' => array(
|
|
'Special:Unblock',
|
|
'Special:UncategorizedCategories',
|
|
'Special:UncategorizedFiles',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Special page name',
|
|
'query' => 'Special:EditWatchlist',
|
|
'results' => array(
|
|
'Special:EditWatchlist',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Special page subpages',
|
|
'query' => 'Special:EditWatchlist/',
|
|
'results' => array(
|
|
'Special:EditWatchlist/clear',
|
|
'Special:EditWatchlist/raw',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Special page subpages with prefix',
|
|
'query' => 'Special:EditWatchlist/cl',
|
|
'results' => array(
|
|
'Special:EditWatchlist/clear',
|
|
),
|
|
) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideSearch
|
|
* @covers PrefixSearch::search
|
|
* @covers PrefixSearch::searchBackend
|
|
*/
|
|
public function testSearch( Array $case ) {
|
|
$this->searchProvision( null );
|
|
$searcher = new StringPrefixSearch;
|
|
$results = $searcher->search( $case['query'], 3 );
|
|
$this->assertEquals(
|
|
$case['results'],
|
|
$results,
|
|
$case[0]
|
|
);
|
|
}
|
|
|
|
public static function provideSearchBackend() {
|
|
return array(
|
|
array( array(
|
|
'Simple case',
|
|
'provision' => array(
|
|
'Bar',
|
|
'Barcelona',
|
|
'Barbara',
|
|
),
|
|
'query' => 'Bar',
|
|
'results' => array(
|
|
'Bar',
|
|
'Barcelona',
|
|
'Barbara',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Exact match not on top (bug 70958)',
|
|
'provision' => array(
|
|
'Barcelona',
|
|
'Bar',
|
|
'Barbara',
|
|
),
|
|
'query' => 'Bar',
|
|
'results' => array(
|
|
'Bar',
|
|
'Barcelona',
|
|
'Barbara',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Exact match missing (bug 70958)',
|
|
'provision' => array(
|
|
'Barcelona',
|
|
'Barbara',
|
|
'Bart',
|
|
),
|
|
'query' => 'Bar',
|
|
'results' => array(
|
|
'Bar',
|
|
'Barcelona',
|
|
'Barbara',
|
|
),
|
|
) ),
|
|
array( array(
|
|
'Exact match missing and not existing',
|
|
'provision' => array(
|
|
'Exile',
|
|
'Exist',
|
|
'External',
|
|
),
|
|
'query' => 'Ex',
|
|
'results' => array(
|
|
'Exile',
|
|
'Exist',
|
|
'External',
|
|
),
|
|
) ),
|
|
array( array(
|
|
"Exact match shouldn't override already found match if " .
|
|
"exact is redirect and found isn't",
|
|
'provision' => array(
|
|
// Target of the exact match is low in the list
|
|
'Redirect Test Worse Result',
|
|
'Redirect Test',
|
|
),
|
|
'query' => 'redirect test',
|
|
'results' => array(
|
|
// Redirect target is pulled up and exact match isn't added
|
|
'Redirect Test',
|
|
'Redirect Test Worse Result',
|
|
),
|
|
) ),
|
|
array( array(
|
|
"Exact match shouldn't override already found match if " .
|
|
"both exact match and found match are redirect",
|
|
'provision' => array(
|
|
// Another redirect to the same target as the exact match
|
|
// is low in the list
|
|
'Redirect Test2 Worse Result',
|
|
'Redirect test2',
|
|
),
|
|
'query' => 'redirect TEST2',
|
|
'results' => array(
|
|
// Found redirect is pulled to the top and exact match isn't
|
|
// added
|
|
'Redirect test2',
|
|
'Redirect Test2 Worse Result',
|
|
),
|
|
) ),
|
|
array( array(
|
|
"Exact match should override any already found matches that " .
|
|
"are redirects to it",
|
|
'provision' => array(
|
|
// Another redirect to the same target as the exact match
|
|
// is low in the list
|
|
'Redirect Test Worse Result',
|
|
'Redirect test',
|
|
),
|
|
'query' => 'Redirect Test',
|
|
'results' => array(
|
|
// Found redirect is pulled to the top and exact match isn't
|
|
// added
|
|
'Redirect Test',
|
|
'Redirect Test Worse Result',
|
|
),
|
|
) ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideSearchBackend
|
|
* @covers PrefixSearch::searchBackend
|
|
*/
|
|
public function testSearchBackend( Array $case ) {
|
|
$this->searchProvision( $case['provision'] );
|
|
$searcher = new StringPrefixSearch;
|
|
$results = $searcher->search( $case['query'], 3 );
|
|
$this->assertEquals(
|
|
$case['results'],
|
|
$results,
|
|
$case[0]
|
|
);
|
|
}
|
|
}
|