3 namespace MediaWiki\Tests\Api\Query
;
6 use MediaWiki\MainConfigNames
;
7 use MediaWiki\Revision\RevisionLookup
;
8 use MediaWiki\Tests\Api\ApiTestCase
;
9 use MediaWiki\Title\Title
;
12 use MockSearchResultSet
;
16 * @covers \MediaWiki\Api\ApiQuerySearch
18 class ApiQuerySearchTest
extends ApiTestCase
{
20 protected function setUp(): void
{
22 MockSearchEngine
::clearMockResults();
23 $this->registerMockSearchEngine();
24 $this->setService( 'RevisionLookup', $this->createMock( RevisionLookup
::class ) );
27 private function registerMockSearchEngine() {
28 $this->overrideConfigValue( MainConfigNames
::SearchType
, MockSearchEngine
::class );
31 public function provideSearchResults() {
33 'empty search result' => [ [], [] ],
34 'has search results' => [
36 [ $this->mockResultClosure( 'Zomg' ) ],
38 'filters broken search results' => [
41 $this->mockResultClosure( 'a' ),
42 $this->mockResultClosure( 'Zomg', [ 'setBrokenTitle' => true ] ),
43 $this->mockResultClosure( 'b' ),
46 'filters results with missing revision' => [
49 $this->mockResultClosure( 'Zomg', [ 'setMissingRevision' => true ] ),
50 $this->mockResultClosure( 'b' ),
51 $this->mockResultClosure( 'a' ),
58 * @dataProvider provideSearchResults
60 public function testSearchResults( $expect, $hits, array $params = [] ) {
61 MockSearchEngine
::addMockResults( 'my query', $hits );
62 [ $response, $request ] = $this->doApiRequest( $params +
[
65 'srsearch' => 'my query',
67 $titles = array_column( $response['query']['search'], 'title' );
68 $this->assertEquals( $expect, $titles );
71 public function provideInterwikiResults() {
73 'empty' => [ [], [] ],
74 'one wiki response' => [
75 [ 'utwiki' => [ 'Qwerty' ] ],
77 ISearchResultSet
::SECONDARY_RESULTS
=> [
78 'utwiki' => new MockSearchResultSet( [
79 $this->mockResultClosure(
81 [ 'setInterwikiPrefix' => 'utwiki' ]
91 * @dataProvider provideInterwikiResults
93 public function testInterwikiResults( $expect, $hits, array $params = [] ) {
94 MockSearchEngine
::setMockInterwikiResults( $hits );
95 [ $response, $request ] = $this->doApiRequest( $params +
[
98 'srsearch' => 'my query',
99 'srinterwiki' => true,
102 $this->assertArrayNotHasKey( 'interwikisearch', $response['query'] );
106 $this->assertArrayHasKey( 'interwikisearchinfo', $response['query'] );
107 foreach ( $response['query']['interwikisearch'] as $wiki => $wikiResults ) {
108 $results[$wiki] = [];
109 foreach ( $wikiResults as $wikiResult ) {
110 $results[$wiki][] = $wikiResult['title'];
113 $this->assertEquals( $expect, $results );
117 * Returns a closure that evaluates to a MockSearchResult, to be resolved by
118 * MockSearchEngine::addMockResults() or MockresultSet::extractResults().
120 * This is needed because MockSearchResults cannot be instantiated in a data provider,
121 * since they load revisions. This would hit the "real" database instead of the mock
122 * database, which in turn may cause cache pollution and other inconsistencies, see T202641.
124 * @param string $titleText
125 * @param array $setters
126 * @return callable function(): MockSearchResult
128 private function mockResultClosure( $titleText, $setters = [] ) {
129 return static function () use ( $titleText, $setters ) {
130 $title = Title
::newFromText( $titleText );
131 $title->resetArticleID( 0 );
132 $result = new MockSearchResult( $title );
134 foreach ( $setters as $method => $param ) {
135 $result->$method( $param );